[Haskell-beginners] Help with TAP implemation in haskell
Patrick LeBoutillier
patrick.leboutillier at gmail.com
Tue Feb 24 20:32:49 EST 2009
Hi,
As a learning exercise, I'm trying to make a Haskell module (my first)
that implements a TAP library (http://testanything.org/).
The library basically provides some functions to perform unit tests
and keeps track of some state. It also performs quite a bit of IO as
it goes a long.
As a first step I'm loosely basing my code on a Java implementation.
You can find the code here:
http://svn.solucorp.qc.ca/repos/solucorp/JTap/trunk/JTap.java.
I've setup my TapState data structure and a monad transformer to be
able to keep state and do IO within the same functions:
data TapState = TapState {
planSet :: Bool,
noPlan :: Bool,
skipAll :: Bool,
testDied :: Bool,
expectedTests :: Int,
executedTests :: Int,
failedTests :: Int
} deriving (Show)
type TAP a = StateT TapState IO a
In the Java version there is a function called cleanup that is called
after all the tests are performed to determine the return code and
print some diagnostics:
private int cleanup(){
int rc = 0 ;
if (! plan_set){
diag("Looks like your test died before it could output anything.") ;
return rc ;
}
if (test_died){
diag("Looks like your test died just after " + executed_tests + ".") ;
return rc ;
}
if ((! skip_all)&&(no_plan)){
print_plan(executed_tests) ;
}
if ((! no_plan)&&(expected_tests < executed_tests)) {
diag("Looks like you planned " + expected_tests + " test" +
(expected_tests > 1 ? "s" : "") + " but ran "
+ (executed_tests - expected_tests) + " extra.") ;
rc = -1 ;
}
if ((! no_plan)&&(expected_tests > executed_tests)) {
diag("Looks like you planned " + expected_tests + " test" +
(expected_tests > 1 ? "s" : "") + " but only ran "
+ executed_tests + ".") ;
}
if (failed_tests > 0){
diag("Looks like you failed " + failed_tests + " test" +
(failed_tests > 1 ? "s" : "") + " of " + executed_tests + ".") ;
}
return rc ;
}
I'm having problems implementing the equivalent of this function in
haskell. Inside a do block, is there a way to terminate the function
immediately and return a result ("return" in the imperative sense, not
the Haskell sense)? If not, must one really use deeply nested
if/then/else statements to treat these special cases? All I could come
up was this, which I find quite ugly:
_cleanup :: Int -> TAP Int
_cleanup rc = do
ts <- get
if (not $ planSet ts)
then do
diag "Looks like your test died before it could output anything."
return rc
else if (testDied ts)
then do
diag $ "Looks like your test died just after " ++
(show $ executedTests ts)
return rc
else ...
Thanks a lot,
Patrick
Note: If it helps, you can find my Haskell code here:
http://svn.solucorp.qc.ca/repos/solucorp/JTap/trunk/tap.hs
--
=====================
Patrick LeBoutillier
Rosemère, Québec, Canada
More information about the Beginners
mailing list