-- Print tests in any of the supported formats. -- Useful for debugging and for migrating between formats. -- Issues: -- converting v1 -> v2/v3 -- a >>>= 0 often gets converted to a >>>2 // or >2 //, when >= or nothing would be preferred (but semantically less accurate, therefore risky to choose automatically) -- converting v3 -> v3 -- loses comments at the top of the file, even above an explicit < delimiter -- may lose other data module Print where import Safe (lastMay) import Import import Types -- | Print a shell test. See CLI documentation for details. -- For v3 (the preferred, lightweight format), avoid printing most unnecessary things -- (stdout delimiter, 0 exit status value). printShellTest :: String -- ^ Shelltest format. Value of option @--print[=FORMAT]@. -> ShellTest -- ^ Test to print -> IO () printShellTest format ShellTest{command=c,stdin=i,comments=comments,trailingComments=trailingComments, stdoutExpected=o_expected,stderrExpected=e_expected,exitCodeExpected=x_expected} = do case format of "v1" -> do printComments comments printCommand "" c printStdin "<<<" i printStdouterr False ">>>" o_expected printStdouterr False ">>>2" e_expected printExitStatus True True ">>>=" x_expected printComments trailingComments "v2" -> do printComments comments printStdin "<<<" i printCommand "$$$ " c printStdouterr True ">>>" o_expected printStdouterr True ">>>2" e_expected printExitStatus trailingblanklines True ">>>=" x_expected printComments trailingComments "v3" -> do printComments comments printStdin "<" i printCommand "$ " c printStdouterr True ">" o_expected printStdouterr True ">2" e_expected printExitStatus trailingblanklines False ">=" x_expected printComments trailingComments _ -> fail $ "Unsupported --print format: " ++ format where trailingblanklines = case (o_expected, e_expected) of (Just (Lines _ o), Just (Lines _ e)) -> hasblanks $ if null e then o else e _ -> False where hasblanks s = maybe False null $ lastMay $ lines s printComments :: [String] -> IO () printComments = mapM_ putStrLn printStdin :: String -> Maybe String -> IO () printStdin _ (Just "") = return () printStdin _ Nothing = return () printStdin prefix (Just s) = printf "%s\n%s" prefix s printCommand :: String -> TestCommand -> IO () printCommand prefix (ReplaceableCommand s) = printf "%s%s\n" prefix s printCommand prefix (FixedCommand s) = printf "%s %s\n" prefix s -- Print an expected stdout or stderr test, prefixed with the given delimiter. -- If no expected value is specified, print nothing if first argument is true -- (for format 1, which ignores unspecified out/err), otherwise print a dummy test. printStdouterr :: Bool -> String -> Maybe Matcher -> IO () printStdouterr alwaystest prefix Nothing = when alwaystest $ printf "%s //\n" prefix printStdouterr _ _ (Just (Lines _ "")) = return () printStdouterr _ _ (Just (Numeric _)) = fail "FATAL: Cannot handle Matcher (Numeric) for stdout/stderr." printStdouterr _ _ (Just (NegativeNumeric _)) = fail "FATAL: Cannot handle Matcher (NegativeNumeric) for stdout/stderr." printStdouterr _ prefix (Just (Lines _ s)) | prefix==">" = printf "%s" s -- omit v3's > delimiter, really no need for it printStdouterr _ prefix (Just (Lines _ s)) = printf "%s\n%s" prefix s printStdouterr _ prefix (Just regex) = printf "%s %s\n" prefix (show regex) -- | Print an expected exit status clause, prefixed with the given delimiter. -- If zero is expected: -- if the first argument is not true, nothing will be printed; -- otherwise if the second argument is not true, only the delimiter will be printed. printExitStatus :: Bool -> Bool -> String -> Matcher -> IO () printExitStatus _ _ _ (Lines _ _) = fail "FATAL: Cannot handle Matcher (Lines) for exit status." printExitStatus always showzero prefix (Numeric "0") = when always $ printf "%s %s\n" prefix (if showzero then "0" else "") printExitStatus _ _ prefix s = printf "%s %s\n" prefix (show s)