Project:Haskell/Test plans

From Gentoo Wiki
Jump to:navigation Jump to:search


This is a list of test cases for packages maintained by the Gentoo Haskell project. When an arch team is stabilizing Haskell software, they often won't know much about the package involved. To make their job easier, we provide example GHCi sessions or small programs which exercise each Haskell package. Then the arch teams can simply follow the instructions, and verify that nothing unusual happens.

If you are familiar with a package and can provide a better test case, please contact us!

Packages with Test Suites

If a package has a passing test suite, we usually consider that sufficient to mark it stable. You can watch the output to ensure that the suite was run and that it passed:

root #FEATURES=test emerge --verbose --oneshot dev-haskell/streaming-commons
 * >>> Test phase [cabal test]: dev-haskell/streaming-commons-0.1.8
./setup test
Running 1 test suites...
Test suite test: RUNNING...
Test suite test: PASS
Test suite logged to: dist/test/streaming-commons-0.1.8-test.log
1 of 1 test suites (1 of 1 test cases) passed.
>>> Completed testing dev-haskell/streaming-commons-0.1.8


GHCi stand for something like, GHC, interactively. It's a REPL environment for the GHC Haskell compiler. Most of the test scenarios will be given as a series of GHCi commands, which either do nothing or produce some output to be checked visually. For example,

user $ghci
ghci> putStrLn "Hello"
ghci> putStrLn "World!"

The ghci> prefix will always be used to indicate the GHCi prompt, even though it will change throughout your session.

During your session, GHCi will usually attempt to load libraries on demand, and output lines like Loading package array- ... linking ... done.. These will be omitted from the session transcripts.

Sometimes we will pass flags to ghci like,

user $ghci -XOverloadedStrings

These flags enable GHC extensions which probably make the test case a whole lot more enjoyable.

Packages without Test Suites

Please keep these in alphabetical order so that the arch teams can find them!


user $ghci
ghci> let s = [72,101,108,108,111,44,32,119,111,114,108,100,33]
ghci> Data.Digest.SHA256.hash s


user $ghci
ghci> import Control.Exception.Base
ghci> import Control.Failure
ghci> exception Overflow :: IO ()
*** Exception: arithmetic overflow
ghci> exception Overflow :: Maybe Int
ghci> exception Overflow :: [Int]


user $ghci test.hs
ghci> prettyPrint t2
ghci> topsort t2
ghci> topsort' t2


user $ghci
ghci> import Data.Text.IDN.IDNA
ghci> import Data.ByteString.Char8
ghci> toUnicode defaultFlags $ pack ""


Save the following as Example.hs:

FILE Example.hs
module Main (main) where
import Prelude

-- The notorious nfib "benchmark", but using Doubles.
main = print (nfib 30)

nfib :: Double -> Double
nfib n = if n <= 1
         then 1
         else nfib (n`subtract`1) + nfib (n`subtract`2) + 1

Now run HsColour on it; you should see a syntax-highlighted version of Example.hs echoed to your terminal:

user $HsColour Example.hs


Any XML file should do here; you could also grab a metadata.xml from your $PORTDIR.

user $wget -q ""
user $ghci -XOverloadedStrings
ghci> import Text.XML.LibXML.SAX
ghci> p <- newParserIO (Just "metadata.xml")
ghci> setCallback p parsedEndDocument (print "foo" >> return True)
ghci> parseComplete p


We have to hide dev-haskell/mtl and explicitly load 'dev-haskell/monads-tf since they provide the same modules.

user $ghci -hide-package mtl -package monads-tf
ghci> import Control.Monad.Cont
ghci> let len :: [a] -> Cont r Int; len l = return (length l)
ghci> runCont (len "123") print


The integer on the last line (the hash) may be variable.

user $ghci
ghci> import Numeric.Natural
ghci> let n = fromIntegral 0 :: Natural
ghci> succ n
ghci> succ n >= n
ghci> fromIntegral (-1) :: Natural
*** Exception: arithmetic underflow
ghci> import Data.Hashable
ghci> hash n


user $ghci
ghci> import Test.HUnit
ghci> import Test.QuickCheck
ghci> import Test.QuickCheck.IO
ghci> quickCheck $ (1 == 2) @?= False
+++ OK, passed 1 tests.


The Text.Regex.TDFA module is also exported by dev-haskell/regex-tdfa-rc , so we have to hide it from ghci.

user $ghci -hide-package regex-tdfa-rc
ghci> import Text.Regex.TDFA
ghci> let str = "a bbbb aa b"
ghci> let regex = "(a+) (b+)"
ghci> str =~ regex :: Bool
ghci> str =~ regex :: Int
ghci> str =~ regex :: MatchArray
array (0,2) [(0,(0,6)),(1,(0,1)),(2,(2,4))]
ghci> str =~ regex :: [[String]]
[["a bbbb","a","bbbb"],["aa b","aa","b"]]


See dev-haskell/regex-tdfa. The test cases are the same, except you'll want to hide dev-haskell/regex-tfda instead. For example,

user $ghci -hide-package regex-tdfa


user $ghci
ghci> import Data.Stringable
ghci> toByteString "Hello"
ghci> toFilePath "Hello"
ghci> toText "Hello"


user $ghci -XOverloadedStrings
ghci> import Data.ByteString
ghci> import Data.ByteString.Search
ghci> let s = "Larry the Cow" :: ByteString
ghci> indices " " s
ghci> breakOn " " s
("Larry","the Cow")


The output in the last line will vary, since it should be the current unix timestamp.

user $ghci
ghci> import System.PosixCompat.Time
ghci> epochTime


The output at the end should be whatever is contained in your /etc/os-release.

user $ghci
ghci> import qualified Data.ByteString as BS
ghci> import qualified Data.ByteString.UTF8 as U
ghci> p <- BS.readFile "/etc/os-release"
ghci> U.toString p


user $ghci
ghci> import UU.PPrint
ghci> pretty [1::Int, 2]