IDEA
----

I've just gotten started using RSpec, and in the process of writing some tests, I came to a realization. Despite having various formatters, like HTML, RSpec is essentially text-based. That is, regardless of the capabilities of other output formats, descriptions are limited to the least-common-denominator form of plain text.

I find, however, that some things are just better described _visually_ -- for a few reasons:

-- "A picture is worth a thousand words." Sometimes it's just tedious to describe an object textually, while a graphic representation can be, erm, _illustrative_. -- Sometimes many descriptions in a spec can differ by only a few words. This makes it cumbersome to determine at a glance what a particular test is doing. Mixing graphics with text goes a long way towards improving this situation.


POTENTIAL IMPLEMENTATION
------------------------

If you've come this far with me, and can see some benefit to this, then let's discuss how this might work. I've taken some time to hack in a rudimentary ability to mix graphics into descriptions. Of course, this could only work for graphics capable formatters, like HTMLFormatter. Here's an example from one of my spec files:

describe "'Unification'" do

describe "Given a FeatureStructure with references, and one without," do

    let (:fs1) {newfs(:agreement => {:REF1 => {:number => "sg"}},
                      :subject   => {:agreement => :REF1})}
    let (:fs2) {newfs(:agreement => {:person => "3"})}

    describe "fs1 = !L(fs1)! and fs2 = !L(fs2)!," do
      describe "fs1.unify!(fs2)" do

let (:expected) {newfs(:agreement => {:REF1 => {:number => "sg", :person => "3"}},
                               :subject   => {:agreement => :REF1})}

        it "should be !L(expected)!" do
          result = fs1.unify!(fs2)
          result.should == expected
          result.should be_identical_to(fs1)
          result.should be_identical_to(fs2)
        end
      end
    end
  end

Now, what I've done here is modify HTMLFormatter so that descriptions can use textile formatting. Then I've augmented the textile !! image markers to accept an object reference and a formatter to use. You can see this in the line:

            describe "fs1 = !L(fs1)! and fs2 = !L(fs2)!," do

for example. !L(fs1)! says to format the object (fs1) using LaTeX (L). This means that the object returned by fs1 must have a to_latex method. Another possible format could be DOT (D): !D(fs1)!.

The output of the above spec snippet can be found here:

        http://humblehacker.com/boardimages/visual_rspec_example.png


PERFORMANCE
-----------

Needless to say, running latex and post-processing the dvi to obtain a suitable image does not come cheap -- it is drastically slower than the same spec with no images at all. I wouldn't recommend throwing images into every spec just because you can. But for those cases where visual representations are clearly superior, the performance degradation is IMHO justifiable. And running without the HTML formatter does not suffer from this performance issue, but does present a less informative description.

CONCLUSION
----------

I'm not married to this particular implementation, the result of a series of compromises made while trying to add this ability with few changes to RSpec. Being able to produce the output above is really what I'm after. In addition to the above, I would also like to see the ability to similarly control the output of failure messages. I have not yet attempted to implement this.

I'm very interested to hear your opinions on what I've presented here. Comments?


_______________________________________________
rspec-users mailing list
[email protected]
http://rubyforge.org/mailman/listinfo/rspec-users

Reply via email to