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?