language-bash 0.6.1 → 0.6.2
raw patch · 5 files changed
+97/−26 lines, 5 filesdep +tasty-expected-failuredep +tasty-hunitdep ~transformers
Dependencies added: tasty-expected-failure, tasty-hunit
Dependency ranges changed: transformers
Files
- .gitignore +1/−0
- language-bash.cabal +6/−4
- src/Language/Bash/Parse.hs +4/−6
- src/Language/Bash/Parse/Word.hs +3/−3
- tests/Tests.hs +83/−13
.gitignore view
@@ -3,3 +3,4 @@ cabal.sandbox.config *.o *.hi+.stack-work
language-bash.cabal view
@@ -1,11 +1,11 @@ name: language-bash-version: 0.6.1+version: 0.6.2 category: Language license: BSD3 license-file: LICENSE author: Kyle Raftogianis maintainer: Kyle Raftogianis <kylerafto@gmail.com>-copyright: Copyright (c) 2013-2015 Kyle Raftogianis+copyright: Copyright (c) 2013-2016 Kyle Raftogianis build-type: Simple cabal-version: >= 1.8 homepage: http://github.com/knrafto/language-bash/@@ -45,7 +45,7 @@ base >= 4.6 && < 5, parsec >= 3.0 && < 4.0, pretty >= 1.0 && < 2.0,- transformers >= 0.2 && < 0.5+ transformers >= 0.2 && < 0.6 ghc-options: -Wall @@ -61,4 +61,6 @@ process, QuickCheck, tasty,- tasty-quickcheck+ tasty-quickcheck,+ tasty-hunit,+ tasty-expected-failure
src/Language/Bash/Parse.hs view
@@ -18,7 +18,6 @@ import qualified Language.Bash.Cond as Cond import Language.Bash.Operator import Language.Bash.Parse.Internal-import Language.Bash.Pretty import Language.Bash.Syntax import Language.Bash.Word (fromString, unquote) @@ -120,8 +119,8 @@ heredocDelimQuoted = fromString heredocDelim /= w h <- heredoc (heredocOp == HereStrip) heredocDelim hereDocument <- if heredocDelimQuoted- then heredocWord h- else return (fromString h)+ then return (fromString h)+ else heredocWord h return Heredoc{..} redirOperator = selectOperator operator <?> "redirection operator"@@ -384,13 +383,12 @@ <?> "function definition" where functionDef1 = FunctionDef- <$> try (word "function" *> (prettyText <$> anyWord)+ <$> try (word "function" *> name <* optional functionParens <* newlineList) <*> functionBody functionDef2 = FunctionDef- <$> try ((prettyText <$> unreservedWord)- <* functionParens <* newlineList)+ <$> try (name <* functionParens <* newlineList) <*> functionBody functionParens = operator "(" <* operator ")"
src/Language/Bash/Parse/Word.hs view
@@ -154,10 +154,10 @@ -- | Parse an arithmetic expression. arith :: Stream s m Char => ParsecT s u m String-arith = B.toString <$> parens <?> "arithmetic expression"+arith = B.toString <$> arithPart <?> "arithmetic expression" where- parens = B.many inner- inner = B.matchedPair '(' ')' parens+ arithPart = B.many inner+ inner = B.noneOf "()" <|> B.char '(' <+> arithPart <+> B.char ')' -- | Parse a parenthesized substitution. subst :: Stream s m Char => ParsecT s u m String
tests/Tests.hs view
@@ -1,22 +1,29 @@ 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 Control.Applicative ((<$>))+import System.Process (readProcess)+import Test.QuickCheck+import Test.QuickCheck.Monadic as QCM+import Test.Tasty+import Test.Tasty.QuickCheck+import Test.Tasty.HUnit+import Test.Tasty.ExpectedFailure (expectFail)+import Text.Parsec (parse)+import Text.Parsec.Error (ParseError) -import Language.Bash.Expand (braceExpand)-import Language.Bash.Parse.Word (word)-import Language.Bash.Word (unquote) +import qualified Language.Bash.Parse as Parse+import Language.Bash.Syntax+import qualified Language.Bash.Cond as Cond+import Language.Bash.Word+import Language.Bash.Expand (braceExpand)+import Language.Bash.Parse.Word (word)+ -- TODO sequence braceExpr :: Gen String braceExpr = concat <$> listOf charset where- charset = oneof $+ charset = oneof [ elements ["{", ",", "}"] , elements ["\\ ", "\\{", "\\,", "\\}"] , (:[]) <$> elements ['a'..'z']@@ -37,10 +44,73 @@ prop_expandsLikeBash = monadicIO $ forAllM braceExpr $ \str -> do bash <- run $ expandWithBash str let check = unwords . filter (not . null) $ testExpand str- assert (bash == check)+ run $ putStrLn bash+ run $ putStrLn check+ QCM.assert (bash == check) +properties :: TestTree+properties = testGroup "Properties" [testProperty "brace expansion" prop_expandsLikeBash]++testMatches :: (Eq a, Show a) => TestName -> Either Text.Parsec.Error.ParseError a -> a -> TestTree+testMatches name parsed expected = testCase name $+ case parsed of+ Left err -> assertFailure $ "parseError: " ++ show err+ Right ans -> expected @=? ans++wrapCommand :: Command -> List+wrapCommand c = List [Statement (Last Pipeline {timed = False, timedPosix = False, inverted = False, commands = [c]}) Sequential]++tp :: TestName -> Command -> TestTree+tp source expected = testMatches (filter ((/=) '\n') source)+ (Parse.parse "source" source)+ (wrapCommand expected)++expandString :: String -> [Span]+expandString = map Char++unittests :: TestTree+unittests = testGroup "Unit tests"+ [+ testMatches "testTest"+ (Cond.parseTestExpr ["!", "-e", "\"asd\""])+ (Cond.Not (Cond.Unary Cond.FileExists "\"asd\""))+ , tp "\"$(ls)\""+ (Command (SimpleCommand [] [[Double [CommandSubst "ls"]]]) [])+ , tp "arguments=()"+ (Command (SimpleCommand [Assign (Parameter "arguments" Nothing) Equals (RArray [])] []) [])+ , tp "cat <<EOF\nasd\\`\nEOF"+ (Command+ (SimpleCommand [] [expandString "cat"])+ [Heredoc {heredocOp = Here,+ heredocDelim = "EOF",+ heredocDelimQuoted = False,+ hereDocument = [Char 'a',Char 's',Char 'd',Escape '`',+ Char '\n']}])+ , tp "cat <<\"EOF\"\nasd\\`\nEOF"+ (Command+ (SimpleCommand [] [expandString "cat"])+ [Heredoc {heredocOp = Here,+ heredocDelim = "EOF",+ heredocDelimQuoted = True,+ hereDocument = expandString "asd\\`\n"}])+ , tp "echo $((2 + 2))"+ (Command+ (SimpleCommand [] [expandString "echo", [ArithSubst "2 + 2"]])+ [])+ , tp "((2 + 2))"+ (Command (Arith "2 + 2") [])+ , tp "echo $(((2 + 2)))"+ (Command+ (SimpleCommand [] [expandString "echo", [ArithSubst "(2 + 2)"]])+ [])+ ]++failingtests :: TestTree+failingtests = testGroup "Failing tests" (map expectFail+ [])+ tests :: TestTree-tests = testProperty "brace expansion" prop_expandsLikeBash+tests = testGroup "Tests" [properties, unittests, failingtests] main :: IO () main = defaultMain tests