module Main (main) where
import Control.Applicative
import System.Process (readProcess)
import Test.QuickCheck
import Test.QuickCheck.Monadic
import Test.Tasty
import Test.Tasty.QuickCheck
import Text.Parsec (parse)
import Language.Bash.Expand (braceExpand)
import Language.Bash.Parse.Word (word)
import Language.Bash.Word (unquote)
-- TODO sequence
braceExpr :: Gen String
braceExpr = concat <$> listOf charset
where
charset = oneof $
[ elements ["{", ",", "}"]
, elements ["\\ ", "\\{", "\\,", "\\}"]
, (:[]) <$> elements ['a'..'z']
]
expandWithBash :: String -> IO String
expandWithBash str = do
expn <- readProcess "/usr/bin/env" ["bash", "-c", "echo " ++ str] ""
return $ filter (`notElem` "\r\n") expn
testExpand :: String -> [String]
testExpand s = case parse word "" s of
Left e -> error (show e)
Right w -> map unquote (braceExpand w)
-- Tests brace expansion.
prop_expandsLikeBash :: Property
prop_expandsLikeBash = monadicIO $ forAllM braceExpr $ \str -> do
bash <- run $ expandWithBash str
let check = unwords . filter (not . null) $ testExpand str
assert (bash == check)
tests :: TestTree
tests = testProperty "brace expansion" prop_expandsLikeBash
main :: IO ()
main = defaultMain tests