A couple of weeks ago I found my self writing some C code. Dropping down to a lower level language like C can always be painful when you have been spending too much time in the land of dynamic languages. Interestingly enough, it was not Ruby's Enumerable that was causing the most withdrawal pain but in fact the aspect I was missing most about my Ruby environment was rSpec. If you have not checked out rSpec or any other BDD testing suite I would highly recommend it. rSpec has helped me learn what TDD is suppose to really be about and has changed the way I code. Anyways, I had remembered seeing a post about how you could now use rSpec to spec out your Java code and began wondering if the same could be done with C.

Well, it turns out with that with little of help from SWIG it is quite easy to BDD your C with rSpec. For those late to the party, SWIG is a really cool tool that generates wrappers for C/C++ code that other languages (generally scripting languages) can use. All that you need to do is create an interface file for swig to parse that correlates with the C/C++ that you wish to generate wrappers for.

To illustrate how to use SWIG in conjunction with rSpec lets take a look at what seems to of become the canonical rSpec example, Bowling. This looks slightly different because of the C twist to it:

# bowling_spec.rbrequire'bowling'describeBowlingdo#Note, I am not creating a new Bowling object...# But rather I am testing the functional C code as stand alone module.it"should score 0 for gutter game"do20.times{Bowling.hit(0)}Bowling.score.should==0endend

Now, the corresponding C code that will put our spec in the green:

//bowling.cvoidhit(intpins){}intscore(){return0;}

The interface file required by SWIG to generate the wrappers is as follows:

%modulebowlingvoidhit(intpins);intscore();

Once those are in place you run SWIG to generate the wrappers, use 'mkmf' to generate the Makefile (just like a you were making a C extension for Ruby), make, and then spec. This one-off ruby script shows the steps:

Like I said this is a very simple example. I was only using rSpec to BDD some simple C functions so the above steps worked perfectly for me. As you need to spec more complicated C code I would suggest looking at the SWIG and Ruby reference. This page covers how to deal with variable linking, pointers, etc... One thing that I did run into that I should point out is that module names will not be camel case as seen in idiomatic Ruby.. So 'bowling_pin.c" after SWIG got through with it would be used in your specs like Bowling_pin and not BowingPin. You might be able so change this easily with a SWIG flag or setting in the interface file but I didn't bother finding out.

I hope this helps someone and if you find this useful and end up taking/automating this process further please let me know.

About

Ben currently works at Red Brain Labs where he gets to work with machine learning and do polyglot programming. :)
He earned his Bachelors and Master degrees in Computer Science (graduate work was in graphics and machine learning) from the University of Utah. The areas of machine learning, software gardening, and programming languages usually keep him busy. Online he is known as @bmabey.
In his "real" life he enjoys spending time with his family, running and doing triathlons.