test-framework-th (empty) → 0.1.2
raw patch · 3 files changed
+184/−0 lines, 3 filesdep +basedep +haskell-src-extsdep +haskell98setup-changed
Dependencies added: base, haskell-src-exts, haskell98, language-haskell-extract, regex-posix, template-haskell, test-framework
Files
- Setup.lhs +6/−0
- src/Test/Framework/TH.hs +110/−0
- test-framework-th.cabal +68/−0
+ Setup.lhs view
@@ -0,0 +1,6 @@+#!/usr/bin/runhaskell +> module Main where+> import Distribution.Simple+> main :: IO ()+> main = defaultMain+
+ src/Test/Framework/TH.hs view
@@ -0,0 +1,110 @@+-----------------------------------------------------------------------------+--+-- Module : MainTestGenerator+-- Copyright : +-- License : BSD4+--+-- Maintainer : Oscar Finnsson+-- Stability : +-- Portability : +--+-- +-----------------------------------------------------------------------------+{-# OPTIONS_GHC -fglasgow-exts -XTemplateHaskell #-}++module Test.Framework.TH (+ defaultMainGenerator,+ testGroupGenerator+) where+import Language.Haskell.TH+import Language.Haskell.Exts.Parser+import Language.Haskell.Exts.Syntax+import Text.Regex.Posix+import Maybe+import Language.Haskell.Exts.Extension+import Language.Haskell.Extract ++import Test.Framework (defaultMain, testGroup)++-- | Generate the usual code and extract the usual functions needed in order to run HUnit/Quickcheck/Quickcheck2.+-- All functions beginning with case_ or prop_ will be extracted.+-- +-- > {-# OPTIONS_GHC -fglasgow-exts -XTemplateHaskell #-}+-- > module MyModuleTest where+-- > import Test.HUnit+-- > import MainTestGenerator+-- > +-- > main = $(defaultMainGenerator)+-- >+-- > case_Foo = do 4 @=? 4+-- >+-- > case_Bar = do "hej" @=? "hej"+-- > +-- > prop_Reverse xs = reverse (reverse xs) == xs+-- > where types = xs :: [Int]+-- +-- will automagically extract prop_Reverse, case_Foo and case_Bar and run them as well as present them as belonging to the testGroup 'MyModuleTest' such as+--+-- > me: runghc MyModuleTest.hs +-- > MyModuleTest:+-- > Reverse: [OK, passed 100 tests]+-- > Foo: [OK]+-- > Bar: [OK]+-- > +-- > Properties Test Cases Total +-- > Passed 1 2 3 +-- > Failed 0 0 0 +-- > Total 1 1 3+ +-- +defaultMainGenerator :: ExpQ+defaultMainGenerator = + [| defaultMain [ testGroup $(locationModule) $ $(propListGenerator) ++ $(caseListGenerator) ] |]++-- | Generate the usual code and extract the usual functions needed for a testGroup in HUnit/Quickcheck/Quickcheck2.+-- All functions beginning with case_ or prop_ will be extracted.+-- +-- > -- file SomeModule.hs+-- > fooTestGroup = $(testGroupGenerator)+-- > main = defaultMain [fooTestGroup]+-- > case_1 = do 1 @=? 1+-- > case_2 = do 2 @=? 2+-- > prop_p xs = reverse (reverse xs) == xs+-- > where types = xs :: [Int]+-- +-- is the same as+--+-- > -- file SoomeModule.hs+-- > fooTestGroup = testGroup "SomeModule" [testProperty "p" prop_1, testCase "1" case_1, testCase "2" case_2]+-- > main = defaultMain [fooTestGroup]+-- > case_1 = do 1 @=? 1+-- > case_2 = do 2 @=? 2+-- > prop_1 xs = reverse (reverse xs) == xs+-- > where types = xs :: [Int]+--+testGroupGenerator :: ExpQ+testGroupGenerator =+ [| testGroup $(locationModule) $ $(propListGenerator) ++ $(caseListGenerator) |]++listGenerator :: String -> String -> ExpQ+listGenerator beginning funcName =+ functionExtractorMap beginning (applyNameFix funcName)++propListGenerator :: ExpQ+propListGenerator = listGenerator "^prop_" "testProperty"++caseListGenerator :: ExpQ+caseListGenerator = listGenerator "^case_" "testCase"++-- | The same as+-- e.g. \n f -> testProperty (fixName n) f+applyNameFix :: String -> ExpQ+applyNameFix n =+ do fn <- [|fixName|]+ return $ LamE [VarP (mkName "n")] (AppE (VarE (mkName n)) (AppE (fn) (VarE (mkName "n"))))++fixName :: String -> String+fixName name = replace '_' ' ' $ drop 5 name++replace :: Eq a => a -> a -> [a] -> [a]+replace b v = map (\i -> if b == i then v else i)
+ test-framework-th.cabal view
@@ -0,0 +1,68 @@+name: test-framework-th+version: 0.1.2+cabal-version: -any+build-type: Simple+license: BSD3+maintainer: Oscar Finnsson+build-depends: base >= 4 && < 5, test-framework, language-haskell-extract, haskell-src-exts, haskell98, regex-posix, template-haskell+stability:+homepage: http://github.com/finnsson/test-generator+package-url:+bug-reports:+synopsis: Automagically generate the HUnit- and Quickcheck-bulk-code using Template Haskell.+description:+ @test-framework-th@ contains two interesting functions: @defaultMainGenerator@ and @testGroupGenerator@.+ .+ @defaultMainGenerator@ will extract all functions beginning with case_ or prop_ in the module and put them in a testGroup.+ .+ > module Foo where+ > main = $(defaultMainGenerator)+ >+ > case_Two = 2 @=? 2+ > case_Hi = "hi" @=? "hi"+ > prop_Reverse xs = reverse (reverse xs) == xs+ > where types = xs :: [Int]+ .+ is the same as+ .+ > module Foo where+ > main = defaultMain [testGroup "Foo" [testProperty "Reverse" prop_Reverse, testCase "Two" case_Two, testCase "Hi" case_Hi]+ >+ > case_Two = 2 @=? 2+ > case_Hi = "hi" @=? "hi"+ > prop_Reverse xs = reverse (reverse xs) == xs+ > where types = xs :: [Int]+ .+ @testGroupGenerator@ is like @defaultMainGenerator@ but without @defaultMain@. It is useful if you need a function for the testgroup+ (e.g. if you want to be able to call the testgroup from another module).+category: Testing+author: Oscar Finnsson & Emil Nordling+tested-with:+data-files:+data-dir: ""+extra-source-files:+extra-tmp-files:+exposed-modules: Test.Framework.TH +exposed: True+buildable: True+build-tools:+cpp-options:+cc-options:+ld-options:+pkgconfig-depends:+frameworks:+c-sources:+extensions:+extra-libraries:+extra-lib-dirs:+includes:+install-includes:+include-dirs:+hs-source-dirs: src+other-modules:+ghc-prof-options:+ghc-shared-options:+ghc-options:+hugs-options:+nhc98-options:+jhc-options: