{-# LANGUAGE ExistentialQuantification #-} module Golden where import Control.Monad (Monad(..)) import Data.Char (Char) import Data.Function (($)) import Data.Int (Int) import Data.Maybe (Maybe(..)) import Data.Ord (Ord(..)) import Data.Semigroup (Semigroup(..)) import Data.String (IsString(..), String) import Prelude (succ) import System.IO (FilePath) import System.IO.Unsafe (unsafePerformIO) import Test.Tasty import Test.Tasty.Golden import Text.Printf (printf) import Text.Show (Show(..)) import qualified Data.List as List import Paths_symantic_formatter import Symantic.Formatter golden :: TestTree golden = testGroup "Golden" [ testGroup "Plain" $ (\f -> List.zipWith f goldens [1::Int ..]) $ \(Golden fmt inps) fmtNum -> let fmtDir = printf "Format%03d" fmtNum in testGroup fmtDir $ (\f -> List.zipWith f inps [1::Int ..]) $ \inp inpNum -> let plainFile = getGoldenDir $ printf "Plain/%s/Input%02d.expected.txt" fmtDir inpNum in goldenVsStringDiff (printf "Input%02d" inpNum) goldenDiff plainFile $ do return $ fromString $ runPlain fmt inp ] getGoldenDir :: FilePath -> FilePath getGoldenDir p = unsafePerformIO $ getDataFileName $ "tests/Golden/" <> p goldenDiff :: FilePath -> FilePath -> [String] goldenDiff ref new = ["diff", "-u", "-w", "-B", ref, new] data Golden repr = forall inp. Golden (repr inp) [inp] goldens :: Indentable repr => Inferable Char repr => Inferable Int repr => Inferable String repr => IsString (repr ()) => Justifiable repr => Listable repr => Newlineable repr => Repeatable repr => Decorable repr => Voidable repr => Wrappable repr => [Golden repr] goldens = [ let fun t = "function(" .> breakalt t (incrIndent (spaces 2) 2 (newline.>t)<.newline) <. ")" in Golden ( setWidth (Just 19) $ fun $ fun $ fun $ fun $ fun $ bracketList (many int) ) [ [[1..9], [1..9]] , [[0..9], [0..9]] ] , Golden ( setWidth (Just 10) $ justify (unorderedList (unwords_ int)) ) [ [[1..9], [1..9]] ] , Golden ( setWidth (Just 11) $ justify (orderedList (unwords_ int)) ) [ [[1..9], [1..9]] ] , Golden (setWidth (Just 10) $ justify (unorderedList (unorderedList (unwords_ int)))) [ [ [[1..9], [1..9]], [[1..9], [1..9]] ] ] , Golden (setWidth (Just 80) string) [ lorem ] -- breakspace backtracking is bounded by the removable indentation -- (hence it can actually wrap a few words in reasonable time). , Golden (setWidth (Just 80) (justify string)) [ lorem ] , Golden ("let"+>align (unlines_ (fill 6 string<+ "::" <+>string))) [ [ ("abcdef","Char") , ("abcde","Int -> Char -> Char") , ("abcdefghi","Char") ] ] , Golden ("let"+>align (unlines_ (fillOrBreak 6 string<+"::"<+>align string))) [ [ ("abcdef","Char") , ("abcde","Int -> Char -> Char") , ("abcdefghi","Char ->\nChar") ] ] , Golden (setWidth (Just 10) $ nestedAlign 6) [()] , Golden (setWidth (Just 10) $ nestedAlign 7) [()] , Golden (setWidth (Just 10) $ nestedAlign 8) [()] , Golden (setWidth (Just 10) $ nestedAlign 9) [()] , Golden (setWidth (Just 10) $ nestedAlign 10) [()] , Golden (setWidth (Just 10) $ justify $ string <. nestedAlign 2) [ "" , "a b c de " ] , Golden (setWidth (Just 10) $ justify string) -- justify justifies [ "1 2 3 4 5 6" -- justify compresses enclosed spaces , "1 2 3 4 5 6" , " 1 2 3 4 5 6 7 8 9" , " 1 2 3 4 5 6 7 8 9" , "1 2 3 4 5 6 7 8 9 " , "1 2 3 4 5 6 7 8 9 " -- justify does not justify on explicit newlines , "1 2 3 4 5 6 7\n8 9 1 2 3 4 5" ] , Golden (setWidth (Just 10) $ "a b ".> "12" .> align string <.> align string) [ (" 34 5", "") , (" 34", "") , (" 34", " ") , (" 34", " 5") , (" 34", " 56") , (" 34", " 567") , (" 34", " 5678") , (" 34", " 56789") ] -- align flushes the buffer , Golden (setWidth (Just 10) $ justify $ unorderedList $ unwords_ int) [ [[1..9]] ] -- unorderedList flushes the buffer , Golden (setWidth (Just 10) $ justify $ unorderedList $ unwords_ int) [ [[1..9], [1..9]] , [[1..19], [1..19]] , [[100000000..100000009], [100000000..100000009]] , [[1000000000..1000000009], [1000000000..1000000009]] ] , Golden (setWidth (Just 10) $ justify $ unorderedList $ unorderedList $ unwords_ int) [ [ [ [1..9], [1..9] ], [ [1..9], [1..9] ] ] ] , Golden (setWidth (Just 10) $ justify $ orderedList $ orderedList $ unwords_ int) [ [ [ [1..9], [1..9] ], [ [1..9], [1..9] ] ] ] ] nestedAlign :: Indentable repr => Wrappable repr => IsString (repr ()) => Int -> repr a nestedAlign n = go 1 where go i = fromString (show i) .> (if n <= i then empty else align (breakspace .> go (succ i))) lorem :: String lorem = "Lorem ipsum dolor sit amet, Nulla nec tortor. Donec id elit quis purus\ \ consectetur consequat. Nam congue semper tellus. Sed erat dolor,\ \ dapibus sit amet, venenatis ornare, ultrices ut, nisi. Aliquam ante.\ \ Suspendisse scelerisque dui nec velit. Duis augue augue, gravida euismod,\ \ vulputate ac, facilisis id, sem. Morbi in orci. Nulla purus lacus,\ \ pulvinar vel, malesuada ac, mattis nec, quam. Nam molestie scelerisque\ \ quam. Nullam feugiat cursus lacus.orem ipsum dolor sit amet, consectetur\ \ adipiscing elit. Donec libero risus, commodo vitae, pharetra mollis,\ \ posuere eu, pede. Nulla nec tortor. Donec id elit quis purus consectetur\ \ consequat. Nam congue semper tellus. Sed erat dolor, dapibus sit\ \ amet, venenatis ornare, ultrices ut, nisi. Aliquam ante. Suspendisse\ \ scelerisque dui nec velit. Duis augue augue, gravida euismod, vulputate ac,\ \ facilisis id, sem. Morbi in orci. Nulla purus lacus, pulvinar vel,\ \ malesuada ac, mattis nec, quam. Nam molestie scelerisque quam.\ \ Nullam feugiat cursus lacus.orem ipsum dolor sit amet, consectetur\ \ adipiscing elit. Donec libero risus, commodo vitae, pharetra mollis,\ \ posuere eu, pede. Nulla nec tortor. Donec id elit quis purus consectetur\ \ consequat. Nam congue semper tellus. Sed erat dolor, dapibus sit amet,\ \ venenatis ornare, ultrices ut, nisi. Aliquam ante. Suspendisse\ \ scelerisque dui nec velit. Duis augue augue, gravida euismod, vulputate ac,\ \ facilisis id, sem. Morbi in orci. Nulla purus lacus, pulvinar vel,\ \ malesuada ac, mattis nec, quam. Nam molestie scelerisque quam. Nullam\ \ feugiat cursus lacus.orem ipsum dolor sit amet, consectetur adipiscing\ \ elit. Donec libero risus, commodo vitae, pharetra mollis, posuere eu, pede.\ \ Nulla nec tortor. Donec id elit quis purus consectetur consequat. Nam\ \ congue semper tellus. Sed erat dolor, dapibus sit amet, venenatis ornare,\ \ ultrices ut, nisi."