From 1e1d4ee88c638c7efe47142d639f0b0100e1964f Mon Sep 17 00:00:00 2001 From: George Thomas Date: Tue, 2 Dec 2025 08:23:53 +0000 Subject: [PATCH] Use Tasty --- aoc.cabal | 4 ++++ app/Main.hs | 42 ++++++++++++++++++++++++------------------ outputs/examples/1/1 | 1 + outputs/examples/1/2 | 1 + 4 files changed, 30 insertions(+), 18 deletions(-) create mode 100644 outputs/examples/1/1 create mode 100644 outputs/examples/1/2 diff --git a/aoc.cabal b/aoc.cabal index 97382bf..2ec12d5 100644 --- a/aoc.cabal +++ b/aoc.cabal @@ -15,6 +15,7 @@ executable aoc MultiWayIf NoFieldSelectors OverloadedRecordDot + OverloadedStrings ViewPatterns ghc-options: -Wall @@ -36,5 +37,8 @@ executable aoc safe, stm, text, + tasty, + tasty-golden, + tasty-hunit, time, transformers, diff --git a/app/Main.hs b/app/Main.hs index 625b0e9..4ce3f9e 100644 --- a/app/Main.hs +++ b/app/Main.hs @@ -2,24 +2,30 @@ module Main (main) where import Control.Monad.State import Data.Bifunctor -import Data.Foldable +import Data.ByteString.Lazy qualified as BL +import Data.Functor +import Data.Text (Text) +import Data.Text qualified as T +import Data.Text.Encoding (encodeUtf8) +import Test.Tasty +import Test.Tasty.Golden (goldenVsString) import Text.Read (readMaybe) main :: IO () -main = do - runTests puzzle1 +main = + defaultMain $ + testGroup + "tests" + [ puzzleTest puzzle1 + ] -runTests :: Puzzle a -> IO () -runTests p = do - Just input <- p.parse <$> readFile ("inputs/examples/" <> show p.number) - for_ [(1 :: Word, p.part1), (2, p.part2)] \(n, pp) -> - let r = pp.solve input - in putStrLn $ - show n - <> ": " - <> if r == pp.expected - then "correct!" - else "got " <> r <> ", expected " <> pp.expected +puzzleTest :: Puzzle a -> TestTree +puzzleTest p = + withResource (maybe (fail "parse failure") pure . p.parse =<< readFile ("inputs/examples/" <> show p.number)) mempty \input -> + testGroup (show p.number) $ + [(1 :: Word, p.part1), (2, p.part2)] <&> \(n, pp) -> + goldenVsString (show n) ("outputs/examples/" <> show p.number <> "/" <> show n) $ + BL.fromStrict . encodeUtf8 . pp.solve <$> input data Puzzle input = Puzzle { number :: Word @@ -28,8 +34,8 @@ data Puzzle input = Puzzle , part2 :: Part input } data Part input = Part - { solve :: input -> String - , expected :: String + { solve :: input -> Text + , expected :: Text } puzzle1 :: Puzzle [(Direction, Inc)] @@ -47,7 +53,7 @@ puzzle1 = , part1 = Part { solve = - show + T.show . sum . flip evalState 50 . traverse \(d, i) -> state \p -> @@ -58,7 +64,7 @@ puzzle1 = , part2 = Part { solve = - show + T.show . sum . flip evalState 50 . traverse \(d, i) -> state \p -> diff --git a/outputs/examples/1/1 b/outputs/examples/1/1 new file mode 100644 index 0000000..e440e5c --- /dev/null +++ b/outputs/examples/1/1 @@ -0,0 +1 @@ +3 \ No newline at end of file diff --git a/outputs/examples/1/2 b/outputs/examples/1/2 new file mode 100644 index 0000000..62f9457 --- /dev/null +++ b/outputs/examples/1/2 @@ -0,0 +1 @@ +6 \ No newline at end of file