test-framework-th-prime (empty) → 0.0.0
raw patch · 4 files changed
+201/−0 lines, 4 filesdep +basedep +haskell-src-extsdep +language-haskell-extractsetup-changed
Dependencies added: base, haskell-src-exts, language-haskell-extract, regex-posix, template-haskell, test-framework
Files
- LICENSE +32/−0
- Setup.hs +2/−0
- Test/Framework/TH/Prime.hs +144/−0
- test-framework-th-prime.cabal +23/−0
+ LICENSE view
@@ -0,0 +1,32 @@+Copyright (c) 2010, Oscar Finnsson+All rights reserved.++Copyright (c) 2012, IIJ Innovation Institute Inc.+All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions+are met:++ * Redistributions of source code must retain the above copyright+ notice, this list of conditions and the following disclaimer.+ * Redistributions in binary form must reproduce the above copyright+ notice, this list of conditions and the following disclaimer in+ the documentation and/or other materials provided with the+ distribution.+ * Neither the name of the copyright holders nor the names of its+ contributors may be used to endorse or promote products derived+ from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS+FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN+ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE+POSSIBILITY OF SUCH DAMAGE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ Test/Framework/TH/Prime.hs view
@@ -0,0 +1,144 @@+{-# LANGUAGE QuasiQuotes, TemplateHaskell #-}++{-|+ Template Haskell to generate defaultMain with a list of "Test" from+ \"doc_test\", \"case_<somthing>\", and \"prop_<somthing>\".++ An example of source code (Data/MySet.hs):++ > { -| Creating a set from a list. O(N log N)+ >+ > >>> empty == fromList []+ > True+ > >>> singleton 'a' == fromList ['a']+ > True+ > >>> fromList [5,3,5] == fromList [5,3]+ > True+ > - }+ >+ > fromList :: Ord a => [a] -> RBTree a+ > fromList = foldl' (flip insert) empty++ The spaces of comment symbols are due to limitation of haddock.++ An example of test code in the src directory (test/Test.hs):++ > module Main where+ >+ > import Test.Framework.TH.Prime+ > import Test.Framework.Providers.DocTest+ > import Test.Framework.Providers.HUnit+ > import Test.Framework.Providers.QuickCheck2+ > import Test.QuickCheck2+ > import Test.HUnit+ >+ > import Data.MySet+ >+ > main :: IO ()+ > main = $(defaultMainGenerator)+ >+ > doc_test :: DocTests+ > doc_test = docTest ["../Data/MySet.hs"] ["-i.."]+ >+ > prop_toList :: [Int] -> Bool+ > prop_toList xs = ordered ys+ > where+ > ys = toList . fromList $ xs+ > ordered (x:y:xys) = x <= y && ordered (y:xys)+ > ordered _ = True+ >+ > case_ticket4242 :: Assertion+ > case_ticket4242 = (valid $ deleteMin $ deleteMin $ fromList [0,2,5,1,6,4,8,9,7,11,10,3]) @?= True++ And run:++ > test% runghc -i.. Test.hs++ This code is based on Test.Framework.TH by Oscar Finnsson and Emil Nordling+ and the author integrated doctest.++ Examples in haddock document is only used as unit tests at this+ moment. I hope that properties of QuickCheck2 can also be specified in+ haddock document in the future. I guess it's Haskell way of Behavior+ Driven Development.++-}++module Test.Framework.TH.Prime (+ defaultMainGenerator,+ DocTests+) where++import Language.Haskell.Extract+import Language.Haskell.TH+import Language.Haskell.TH.Syntax+import Test.Framework (defaultMain)+import Test.Framework.Providers.API++----------------------------------------------------------------++-- | Type for \"doc_test\".+type DocTests = IO Test++----------------------------------------------------------------++{-|+ Generating defaultMain with a list of "Test" from \"doc_test\",+ \"case_*\", and \"prop_\".+-}+defaultMainGenerator :: ExpQ+defaultMainGenerator = do+ defined <- isDefined docTestKeyword+ if defined+ then [| do TestGroup _ doctests <- $(docListGenerator)+ defaultMain [ testGroup $(locationModule) $ doctests ++ $(caseListGenerator) ++ $(propListGenerator) ] |]+ else [| defaultMain [ testGroup $(locationModule) $ $(caseListGenerator) ++ $(propListGenerator) ] |]++----------------------------------------------------------------+-- code from Test.Framework.TH of test-framework-th+-- by Oscar Finnsson & Emil Nordling++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)++----------------------------------------------------------------+-- code from Hiromi Ishii++isDefined :: String -> Q Bool+isDefined n = do+ return False `recover` do+ VarI (Name _ flavour) _ _ _ <- reify (mkName n)+ loc <- location+ case flavour of+ NameG ns _ mdl -> return (ns == VarName && modString mdl == loc_module loc)+ _ -> return False++----------------------------------------------------------------++docTestKeyword :: String+docTestKeyword = "doc_test"++docListGenerator :: ExpQ+docListGenerator = varE $ mkName docTestKeyword
+ test-framework-th-prime.cabal view
@@ -0,0 +1,23 @@+Name: test-framework-th-prime+Version: 0.0.0+Author: Kazu Yamamoto <kazu@iij.ad.jp>+Maintainer: Kazu Yamamoto <kazu@iij.ad.jp>+License: BSD3+License-File: LICENSE+Synopsis: Template Haskell for test framework+Description: Automatically generates a Test list for+ HUnit, doctest and QuickCheck2.+Category: Testing+Cabal-Version: >= 1.6+Build-Type: Simple+library+ if impl(ghc >= 6.12)+ GHC-Options: -Wall -fno-warn-unused-do-bind+ else+ GHC-Options: -Wall+ Exposed-Modules: Test.Framework.TH.Prime+ Build-Depends: base >= 4 && < 5, test-framework, language-haskell-extract >= 0.2.1, haskell-src-exts, regex-posix, template-haskell++Source-Repository head+ Type: git+ Location: https://github.com/kazu-yamamoto/test-framework-th-prime