tasty-mgolden 0.0.1 → 0.0.2
raw patch · 4 files changed
+152/−10 lines, 4 filesdep +ansi-terminalPVP ok
version bump matches the API change (PVP)
Dependencies added: ansi-terminal
API changes (from Hackage documentation)
+ Test.Tasty.MGolden: diffTest :: String -> IO (Text, Text) -> TestTree
+ Test.Tasty.MGolden: instance Test.Tasty.Core.IsTest Test.Tasty.MGolden.DiffTest
Files
- README.md +100/−0
- src/Test/Tasty/MGolden.hs +41/−5
- tasty-mgolden.cabal +10/−4
- test/HLint.hs +1/−1
+ README.md view
@@ -0,0 +1,100 @@+++# tasty-mgolden++Text based [golden tests](https://ro-che.info/articles/2017-12-04-golden-tests)+for [tasty](https://github.com/feuerbach/tasty), with multi line (colored) diff expectation+failure reporting.++Basically this package can turn any `IO Text` action into a golden test via providing a+`FilePath`.++This package is the small brother of [tasty-golden](https://github.com/feuerbach/tasty-golden)+which also implements the same golden testing pattern.++`tasty-mgolden` is less generic and more opinionated than its bigger brother.+But for that reason can also offer more ergonomic defaults for its core use case:++Golden testing for `IO Text` actions. Where:++* The text value is assuemd to contain multiple lines.+* The expectation failures can be rendered nicely in multi line diffs.+* The diff lines are colored via the tasty infrastructure+* The diff rendering is not done via the external `diff` command, but uses the `Diff` package.++Expectation diffs are rendered like developers are used to:++* Removed lines rendered in red.+* Added lines in green.++## Usage++This is taken from the [example](example) directory in the repository.++To run these execute from repository root:++```+stack build+stack exec tasty-mgolden-example+```++Contents of [example/example-a.txt](example/example-a.txt)++```+foo+bar+```++Contents of [example/example-b.txt](example/example-b.txt)++```+foo+bar+```++Contents: `example/Test.hs`++```haskell+import Test.Tasty+import Test.Tasty.MGolden++main :: IO ()+main = defaultMain $ testGroup "golden tests"+ [ goldenTest "example-a" "example/example-a.txt" $ pure "foo\nbar\n"+ , goldenTest "example-b" "example/example-b.txt" $ pure "foo\nbaz\n"+ ]+```++Output:++```diff+golden tests+ example-a: OK+ example-b: FAIL+ foo+-bar++baz++1 out of 2 tests failed (0.00s)+```++Passing the `--update` flag to accept the changes:++```+golden tests+ example-a: OK+ example-b: OK+ UPDATE++All 2 tests passed (0.00s)+```++### TODOs++PRs on these are welcome.++* Improve the multi line diff reporting to only show a+ minimal context around the changed hunks.+* Add line markers in unified diff format.+* Change to `pathtype` from `filepath`+* Future? Upstream this to `tasty-golden` ?
src/Test/Tasty/MGolden.hs view
@@ -2,9 +2,17 @@ This module implements the [golden testing pattern](https://ro-che.info/articles/2017-12-04-golden-tests). +Please refer to the [README.md](README.md) for usage instructions.+ -} -module Test.Tasty.MGolden (Mode(..), goldenTest, printDetails) where+module Test.Tasty.MGolden+ ( Mode(..)+ , diffTest+ , goldenTest+ , printDetails+ )+where import Control.Applicative (empty) import Prelude hiding (print, putStrLn)@@ -20,6 +28,7 @@ import qualified Data.Algorithm.Diff as Diff import qualified Data.Text as Text import qualified Data.Text.IO as Text+import qualified System.Console.ANSI as ANSI import qualified System.IO.Error as Error -- | Golden test run mode@@ -49,6 +58,13 @@ run options golden _callback = runGolden golden options testOptions = pure . pure $ Option (Proxy :: Proxy Mode) +newtype DiffTest = DiffTest (IO (Text, Text))+ deriving stock Typeable++instance IsTest DiffTest where+ run options test _callback = runDiffTest test options+ testOptions = pure empty+ -- | Define a golden test goldenTest :: String -- ^ Name of the test@@ -57,6 +73,21 @@ -> TestTree goldenTest name expectedPath action = singleTest name Golden{..} +-- | Define a diff test+diffTest+ :: String -- ^ Name of the test+ -> IO (Text, Text) -- ^ action to produce expectation+ -> TestTree+diffTest name = singleTest name . DiffTest++runDiffTest :: DiffTest -> OptionSet -> IO Result+runDiffTest (DiffTest expectation) _options = do+ (expected, actual) <- expectation++ if expected == actual+ then pure $ testPassed empty+ else pure . testFailedDetails empty $ printDetails Text.putStrLn expected actual+ runGolden :: Golden -> OptionSet -> IO Result runGolden golden@Golden{..} options = do actual <- action@@ -67,13 +98,13 @@ =<< tryRead expectedPath absentFile :: Golden -> OptionSet -> Text -> IO Result-absentFile golden@Golden{..} options actual =+absentFile golden options actual = if shouldUpdate options then updateExpected golden actual else pure $ testFailed "file is absent" testExpected :: Golden -> OptionSet -> Text -> Text -> IO Result-testExpected golden@Golden{..} options actual expected =+testExpected golden options actual expected = if expected == actual then pure $ testPassed empty else mismatch options golden expected actual@@ -89,7 +120,12 @@ Text.writeFile expectedPath actual pure $ testPassed "UPDATE" -printDetails :: (Text -> IO ()) -> Text -> Text -> ResultDetailsPrinter+-- | Golden test diff details printer+printDetails+ :: (Text -> IO ()) -- ^ line printer+ -> Text -- ^ expected text+ -> Text -- ^ actual (observed) text+ -> ResultDetailsPrinter printDetails putStrLn expected actual = ResultDetailsPrinter print where print :: Int -> (ConsoleFormat -> IO () -> IO ()) -> IO ()@@ -115,7 +151,7 @@ addFormat = okFormat neutralFormat :: ConsoleFormat-neutralFormat = infoOkFormat+neutralFormat = ConsoleFormat ANSI.NormalIntensity ANSI.Dull ANSI.Black removeFormat :: ConsoleFormat removeFormat = infoFailFormat
tasty-mgolden.cabal view
@@ -1,13 +1,13 @@-cabal-version: 1.12+cabal-version: 1.18 -- This file has been generated from package.yaml by hpack version 0.33.0. -- -- see: https://github.com/sol/hpack ----- hash: e4c5b3bd31a278700368fd88f0680bf44bebc943630afe0e6c01bdc095db8619+-- hash: d24f2ff9d3b958bfb3a52ecb1fbb170ad948d787cbb2001453733218715c2104 name: tasty-mgolden-version: 0.0.1+version: 0.0.2 synopsis: Golden testing provider for tasty with muti-line diff output description: Please visit the README at <https://github.com/mbj/tasty-mgolden#readme> for usage information.@@ -18,8 +18,10 @@ maintainer: Markus Schirp <mbj@schirp-dso.com> license: BSD3 license-file: LICENSE-tested-with: GHC ==8.6.5 || ==8.8.3+tested-with: GHC ==8.6.5 || ==8.8.4 || ==8.10.2 build-type: Simple+extra-doc-files:+ README.md source-repository head type: git@@ -41,6 +43,7 @@ ghc-options: -Wall -Wcompat -Widentities -Wimplicit-prelude -Wincomplete-record-updates -Wincomplete-uni-patterns -Wmissing-exported-signatures -Wmissing-local-signatures -Wmonomorphism-restriction -Wredundant-constraints -funbox-strict-fields build-depends: Diff ==0.3.4 || >=0.4 && <0.5+ , ansi-terminal >=0.9 && <0.10 || >=0.10 && <0.11 , base >=4.12 && <=4.15 , filepath >=1.4.2 && <1.5 , tasty >=1.3.1 && <1.4@@ -57,6 +60,7 @@ ghc-options: -Wall -Wcompat -Widentities -Wimplicit-prelude -Wincomplete-record-updates -Wincomplete-uni-patterns -Wmissing-exported-signatures -Wmissing-local-signatures -Wmonomorphism-restriction -Wredundant-constraints -funbox-strict-fields -rtsopts -threaded -with-rtsopts=-N -Wno-implicit-prelude build-depends: Diff ==0.3.4 || >=0.4 && <0.5+ , ansi-terminal >=0.9 && <0.10 || >=0.10 && <0.11 , base >=4.12 && <=4.15 , filepath >=1.4.2 && <1.5 , tasty >=1.3.1 && <1.4@@ -77,6 +81,7 @@ ghc-options: -Wall -Wcompat -Widentities -Wimplicit-prelude -Wincomplete-record-updates -Wincomplete-uni-patterns -Wmissing-exported-signatures -Wmissing-local-signatures -Wmonomorphism-restriction -Wredundant-constraints -funbox-strict-fields -rtsopts -threaded -with-rtsopts=-N build-depends: Diff ==0.3.4 || >=0.4 && <0.5+ , ansi-terminal >=0.9 && <0.10 || >=0.10 && <0.11 , base >=4.12 && <=4.15 , filepath >=1.4.2 && <1.5 , tasty >=1.3.1 && <1.4@@ -100,6 +105,7 @@ ghc-options: -Wall -Wcompat -Widentities -Wimplicit-prelude -Wincomplete-record-updates -Wincomplete-uni-patterns -Wmissing-exported-signatures -Wmissing-local-signatures -Wmonomorphism-restriction -Wredundant-constraints -funbox-strict-fields -rtsopts -threaded -with-rtsopts=-N build-depends: Diff ==0.3.4 || >=0.4 && <0.5+ , ansi-terminal >=0.9 && <0.10 || >=0.10 && <0.11 , base >=4.12 && <=4.15 , filepath >=1.4.2 && <1.5 , hlint
test/HLint.hs view
@@ -1,6 +1,6 @@ import Control.Monad (unless) import Data.List (null)-import Language.Haskell.HLint3 (hlint)+import Language.Haskell.HLint (hlint) import System.Exit (exitFailure) import System.IO (IO)