This blog has had far too much content about cycling and getting fit and other boring stuff like that. It’s time to return the blog to it’s roots — doing dumb stuff with computers!
I recently added some unit tests to CocoaLibSpotify, the Objective-C Spotify framework I’m responsible for. I’m new to using tests, and the benefits have been great — I’m somewhat a convert to test-driven development now. However, this post isn’t yet another essay on TDD — it’s about how to make your testing AWESOME.
On a recent hackday, I took the Mac mini that builds CocoaLibSpotify and runs the unit tests and gave it a slightly more… visual indicator on the test results.
Yellow = running tests, green = all passed, red = one more more failed.
To accomplish this, I made a simpler version of my previous project to control four individual RGB LED strips. The simplified unit uses an Arduino Uno instead of a Mega2560, and only has two channels instead of four (only one of which is used in this project).
The completed hardware - running wires underneath the board makes it much neater!
Once the hardware was up-and-running, I made a slightly modified version of the control software to go on the Arduino (since the Uno has different PWM pins to the Mega2560) and was ready to go! At this point, the unit is compatible with all of the previous code I’ve written for sending colours, except only channels 1 and 2 do anything.
Next, we get a strip of thin plastic and make a loop roughly the size of the Mac mini’s base, stick a flexible LED strip to it and voilà! One glowing Mac mini!
Linking to Unit Tests
Since this was a hackday, the rest of the project is slightly… slap-dash.
First, I wrote a stupid simple Ruby/Sinatra application that provides a REST API over HTTP, allowing you to push colours with a standard HTTP GET request:
http://localhost:4567/push-color?red=0&green=255&blue=0
The entirety of the code is below in its horrible, hardcoded, fragile glory. It’s worth noting that the Uno uses exactly the same protocol as the Mega, so it still needs to be given four colours even though it only supports two.
require 'sinatra'
require 'serialport'
require 'json'
port = SerialPort.new("/dev/tty.usbmodemfa131", 57600)
get '/push-color' do
# Push one colour to each channel
red = params[:red].to_i
green = params[:green].to_i
blue = params[:blue].to_i
message = Array.new(15, 0)
message[0] = 0xBA
message[1] = 0xBE
message[2] = green
message[3] = blue
message[4] = red
message[5] = green
message[6] = blue
message[7] = red
message[8] = green
message[9] = blue
message[10] = red
message[11] = green
message[12] = blue
message[13] = red
message[14] = 0
for currentIndex in 2..13
message[14] = message[14] ^ message[currentIndex]
end
port.write(message.pack('c*'))
return "<body style=\"background-color:rgb(#{red}, #{green}, #{blue})\">#{message.to_s}</body>"
end
Next, continuing the trend of implementing this in the worst way possible, I added HTTP requests directly into the unit test code in CocoaLibSpotify. If you start the tests with the command-line parameter -StatusColorServer localhost:4567
it’ll make HTTP requests to the given server:
-(void)pushColorToStatusServer:(UIColor *)color {
NSString *statusServerAddress = [[NSUserDefaults standardUserDefaults] stringForKey:kTestStatusServerUserDefaultsKey];
if (statusServerAddress.length == 0) return;
CGFloat red = 0.0;
CGFloat green = 0.0;
CGFloat blue = 0.0;
[color getRed:&red green:&green blue:&blue alpha:NULL];
NSString *requestUrlString = [NSString stringWithFormat:@"http://%@/push-color?red=%lu&green=%lu&blue=%lu",
statusServerAddress,
(NSUInteger)red * 255,
(NSUInteger)green * 255,
(NSUInteger)blue * 255];
NSURL *requestUrl = [NSURL URLWithString:requestUrlString];
NSURLRequest *request = [NSURLRequest requestWithURL:requestUrl
cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData
timeoutInterval:1.0];
[NSURLConnection sendSynchronousRequest:request
returningResponse:nil
error:nil];
}
And that, my friends, is it! The unit tests set the colour to yellow when it starts the tests, then red or green depending on the outcome. Don’t forget to put your IP address on the company IRC so your colleagues can blink the lights all day long!