tasty-th 0.1.6 → 0.1.7
raw patch · 6 files changed
+155/−6 lines, 6 filesdep +tasty-hunitdep +tasty-th
Dependencies added: tasty-hunit, tasty-th
Files
- example-explicit.hs +25/−0
- example-literate.lhs +36/−0
- example.hs +29/−0
- src/Test/Tasty/TH.hs +22/−4
- tasty-th.cabal +18/−2
- tests/Main.hs +25/−0
+ example-explicit.hs view
@@ -0,0 +1,25 @@+{-# LANGUAGE TemplateHaskell #-}+module Main where++import Test.Tasty+import Test.Tasty.TH+import Test.Tasty.QuickCheck+import Test.Tasty.HUnit++main :: IO ()+main = $(defaultMainGeneratorFor "explicit" ["prop_length_append", "case_length_1", "test_plus"])++prop_length_append :: [Int] -> [Int] -> Bool+prop_length_append as bs = length (as ++ bs) == length as + length bs++case_length_1 :: Assertion+case_length_1 = 1 @=? length [()]++case_add :: Assertion+case_add = 7 @=? (3 + 4)++test_plus :: [TestTree]+test_plus =+ [ $(testGroupGeneratorFor "case_add" ["case_add"])+ -- ...+ ]
+ example-literate.lhs view
@@ -0,0 +1,36 @@+This is an example of using tasty-th with literate haskell files.+First, we need to import the library and enable template haskell:++> {-# LANGUAGE TemplateHaskell #-}+> import Test.Tasty+> import Test.Tasty.TH+> import Test.Tasty.QuickCheck+> import Test.Tasty.HUnit++Now, we can write some quickcheck properties:++> prop_length_append :: [Int] -> [Int] -> Bool+> prop_length_append as bs = length (as ++ bs) == length as + length bs++Or write a HUnit test case:++> case_length_1 :: Assertion+> case_length_1 = 1 @=? length [()]++Properties in comments are not run:++prop_comment :: Assertion+prop_comment = assertFailure "property in comment should not be run"++We can also create test trees:++> test_plus :: [TestTree]+> test_plus =+> [ testCase "3 + 4" (7 @=? (3 + 4))+> -- ...+> ]++We only need a main now that collects all our tests:++> main :: IO ()+> main = $(defaultMainGenerator)
+ example.hs view
@@ -0,0 +1,29 @@+{-# LANGUAGE TemplateHaskell #-}+module Main where++import Test.Tasty+import Test.Tasty.TH+import Test.Tasty.QuickCheck+import Test.Tasty.HUnit++main :: IO ()+main = $(defaultMainGenerator)++{-+Properties in comments are not run:++prop_comment :: Assertion+prop_comment = assertFailure "property in comment should not be run"+-}++prop_length_append :: [Int] -> [Int] -> Bool+prop_length_append as bs = length (as ++ bs) == length as + length bs++case_length_1 :: Assertion+case_length_1 = 1 @=? length [()]++test_plus :: [TestTree]+test_plus =+ [ testCase "3 + 4" (7 @=? (3 + 4))+ -- ...+ ]
src/Test/Tasty/TH.hs view
@@ -33,8 +33,11 @@ import Language.Haskell.Exts.Parser (ParseResult(..), defaultParseMode, parseFilename) import qualified Language.Haskell.Exts.Syntax as S import Language.Haskell.TH-import Data.List import Data.Maybe+import Data.Data (gmapQ, Data)+import Data.Typeable (cast)+import Data.List (nub, isPrefixOf, find)+import qualified Data.Foldable as F import Test.Tasty import Prelude@@ -94,10 +97,25 @@ parsed file = case parseFileContentsWithMode (defaultParseMode { parseFilename = filePath }) file of ParseOk parsedModule -> Just (declarations parsedModule) ParseFailed _ _ -> Nothing- declarations (S.Module _ _ _ _ decls) = mapMaybe testFunName decls+ declarations (S.Module _ _ _ _ decls) = concatMap testFunName decls declarations _ = []- testFunName (S.PatBind _ (S.PVar _ (S.Ident _ n)) _ _) = Just n- testFunName _ = Nothing+ testFunName (S.PatBind _ pat _ _) = patternVariables pat+ testFunName (S.FunBind _ clauses) = nub (map clauseName clauses)+ testFunName _ = []+ clauseName (S.Match _ name _ _ _) = nameString name+ clauseName (S.InfixMatch _ _ name _ _ _) = nameString name++-- | Convert a 'Name' to a 'String'+nameString :: S.Name l -> String+nameString (S.Ident _ n) = n+nameString (S.Symbol _ n) = n++-- | Find all variables that are bound in the given pattern.+patternVariables :: Data l => S.Pat l -> [String]+patternVariables = go+ where+ go (S.PVar _ name) = [nameString name]+ go pat = concat $ gmapQ (F.foldMap go . cast) pat -- | Extract the name of the current module. locationModule :: ExpQ
tasty-th.cabal view
@@ -1,6 +1,6 @@ name: tasty-th-version: 0.1.6-cabal-version: >= 1.6+version: 0.1.7+cabal-version: >= 1.8 build-type: Simple license: BSD3 license-file: BSD3.txt@@ -11,12 +11,28 @@ category: Testing author: Oscar Finnsson & Emil Nordling & Benno Fünfstück+extra-source-files:+ example.hs+ example-explicit.hs+ example-literate.lhs library exposed-modules: Test.Tasty.TH build-depends: base >= 4 && < 5, haskell-src-exts >= 1.18.0, tasty, template-haskell hs-source-dirs: src+ ghc-options: -Wall other-extensions: TemplateHaskell++test-suite tasty-th-tests+ hs-source-dirs: tests+ main-is: Main.hs+ build-depends:+ base >= 4 && < 5,+ tasty-hunit,+ tasty-th+ ghc-options: -Wall+ default-language: Haskell2010+ type: exitcode-stdio-1.0 source-repository head type: git
+ tests/Main.hs view
@@ -0,0 +1,25 @@+{-# LANGUAGE TemplateHaskell #-}+import Test.Tasty.TH+import Test.Tasty.HUnit+import Data.List (sort)++main :: IO ()+main = $(defaultMainGenerator)++case_example_test_functions :: Assertion+case_example_test_functions = do+ functions <- extractTestFunctions "example.hs"+ let expected = [ "prop_length_append", "case_length_1", "test_plus" ]+ sort expected @=? sort functions++case_example_explicit_test_functions :: Assertion+case_example_explicit_test_functions = do+ functions <- extractTestFunctions "example-explicit.hs"+ let expected = [ "case_add", "prop_length_append", "case_length_1", "test_plus" ]+ sort expected @=? sort functions++case_example_literate_test_functions :: Assertion+case_example_literate_test_functions = do+ functions <- extractTestFunctions "example-literate.lhs"+ let expected = [ "prop_length_append", "case_length_1", "test_plus" ]+ sort expected @=? sort functions