Thursday, March 13, 2008

A dependency graphs gem

Some days ago I had to do a big refactoring involving almost 100 C# projects, a little monster. I thought it would be very helpful to have a dependency graph that could quickly show me the projects dependencies I was interested in at any given moment and that would let me apply some filters to the result.
I didn't like the few things I found in the net so I did a Ruby program to traverse csproj files and generate a Graphviz graph with the desired results, something like this:


So as I thought this could be useful to a lot of people I decided to make it open source so I created this Rubyforge project to host it.

I made some changes to make it generic so that it could be used for any kind of text files that have parseable dependencies hidden inside.
There are 2 examples stored in a yaml configuration file that deal with C# projects and Ruby requires statements.

So for example, if you want to graph your C# projects you do this from the root directory:

depgraph -type csproj

And if you want to graph the requires dependencies of your Ruby files you do this:

depgraph -type ruby_requires

Then if you add a new entry in the yaml configuration file you'll be able to do this:

depgraph -type [new entry name]

You can also filter by directories and node name regular expressions against source and dependency targets. I'll add more functionality in next releases but it's already usable.

To install it:

gem install DepGraph

As always, check the project's webpage and the specs for more info.

Tuesday, March 4, 2008

A file system integration tests helper

A common problem that arises when creating integration tests against the file system is not having a one on one mapping between test cases and file structures.

The most popular solution is having one generic file structure defined outside the test case (manually or in the test fixture set up) in which a generic set of files are shared among many different test cases.
This works, but the problem is that we lose a lot of the documenting benefit of tests.

The expressive power we could gain by the explicit creation of customized test files for each test case is very important.

Of course we should test all we can inside our unit tests but it's always good to have something in our toolbox in case we have to go to the real thing at some moment.

One example is when you have to deal with highly coupled legacy code in which your only practical solution may be testing directly against it's file inputs and outputs.

So considering all this I made a very simple ruby gem, filetesthelper, that let's you do something like this:

require 'rubygems'
require 'filetesthelper'
include FileTestHelper

...

def test_some_code_that_uses_the_file_system
#Let's say that the current directory here is X

with_files('dir1/file1' => 'file1 content',
'file2' => 'file2 content') do
#Now the current directory changed to Y which
#is a new directory created under Dir.tmpdir
#containing only 'dir1/file1' and 'file2'.

#Put some test code here.
File.open('file2') do |f|
...
end

#When we finish we are back at directory X and
#the Y directory is deleted with all its contents
end


Check the specs for some more details.

To install it just type gem install filetesthelper from the command line.