Trying to Test a Private Method is a Signal That You Need Another Class

Sometimes I find myself wanting to write tests (or stubs) for a private method. It recently occurred to me that I should consider that impulse an indicator that there is another object hiding in my code. If the private method is sufficiently complicated that it requires direct testing, then the class is probably doing too much.

That code should be extracted to a new object that can be tested in isolation.

Beginner's Perspective on Rspec and Test::Unit

The other day Aaron Patterson asked whether it was OK to teach rspec vs Test::Unit for Ruby beginners.

My own experience was that rspec was really confusing at first: it appears to have a lot of magic. The hard part was understanding where methods and matchers came from. I Don’t like magic, I like to understand how things work.

I was familiar with other unit testing frameworks where you inherit from a base class and got access to the assertion functions via inheritance. That made complete sense to me.

But rspec is different: there’s no explicit class definition, and methods that aren’t monkey-patched onto objects appear out of nowhere. And how come I can use a before(:each) block to write to a @ prefixed variable? Isn’t that an instance variable? But I’m not inside a class!

I did, however, prefer the tree-like structure of nested test cases and liked how the code read as a description of behavior rather than a list of assertions.

Attempting to write my own DSL a few months later helped me piece together a rough understanding of how all that magic works.

Hint: Its not actually magic.

Making guard-phpunit2 Realtime

I’ve been using guard and guard-phpunit2 for unit testing PHP code at work. (Hey, at least there are tests)

One of my main difficulties with it is that it did not show output in real-time. It ships with a really nice rspec inspired result printer, but unfortunately during a run of a large test-suite you can’t see any output until the entire thing is done.

Poor Man's Git Deployment System

Poor man’s git based deployment for a Rails app on cheap shared hosting (runs under passenger):

~/electricfieldhockey.com/deploy.sh
#!/bin/bash # remove the database.yml so we Don't get a merge-conflict # we don't want to keep the config in git, especially if its posted online like # GitHub rm config/database.yml # git pull the new code down, saving the output to a file for later # processing env -i git pull --stat | tee tmp/last-pull.txt # If that last pull included the word "Gemfile" then trigger bundle install if grep -q Gemfile tmp/last-pull.txt; then bundle install fi # if that last pull included any migrations, then trigger rake db:migrate if grep -q migrate tmp/last-pull.txt; then rake db:migrate fi # restore the backup database.yml cp efh.database.yml config/database.yml # changing the time stamp on tmp/restart.txt tells passenger to reload the # application on the next request touch tmp/restart.txt # Fire a request to make passenger boot curl http://electricfieldhockey.com

Then just add a git hook:

~/repos/efh.git/hooks/post-receive
#!/bin/bash while read oldrev newrev refname do branch=$(git rev-parse --symbolic --abbrev-ref $refname) if [ "master" == "$branch" ]; then cd ~/electricfieldhockey.com ./deploy.sh fi done

Multiple Angular.js Versions on the Same Page

We found out today that the following doesn’t work if your app uses JSONP because angular expects the handlers to exist in the global window.angular object. YMMV. I’ll update if we come up with a fix.

UPDATE 2017-10-17: This article is over 3 years old, and is one of the most visited on my site, but I don’t think I would stand behind this advice anymore. More modern builds of angular probably don’t depend on setting the window.angular global variable. By using your favorite build system, you probably don’t need any of these shenanigans. I’m keeping it around because of its pedagogic value for some complex javascript patterns.

i.e. angular.noConflict()

In some instances you may need to include multiple versions of angular.js within the same page. This can happen when writing a third-party widget that you want your customers to embed onto their pages. Part of being a good citizen is not stomping all over their global variables and overwriting their version of angular.js.

Trying to load two incompatible versions of angular can also cause errors that take down both your widget and your customer’s site.

Imagine that we are writing a widget that depends on the latest angular.js (as of the time of this writing, 1.2.7). But our widget is going to be embedded onto a page that already utilizes a much older version (1.0.4). How can we go about loading our script and our dependencies without interfering with the existing page’s scripts?

git lol

[12:14:41 mburke]$ git commit -am "make css important!!!!!!!"
git commit -am "make css importantgit statusgit statusgit status"
[master ac4f622] make css importantgit statusgit statusgit status
 1 file changed, 4 insertions(+), 4 deletions(-)

Thanks, BASH expansion.