packages feed

hspec-golden 0.2.1.0 → 0.2.2.0

raw patch · 6 files changed

+155/−39 lines, 6 filesdep +ansi-terminaldep ~directorydep ~hspec-coredep ~optparse-applicativenew-uploader

Dependencies added: ansi-terminal

Dependency ranges changed: directory, hspec-core, optparse-applicative

Files

ChangeLog.md view
@@ -1,4 +1,12 @@ # Changelog for hspec-golden+## 0.2.2.0+#### Add+* `golden` helper to write tests++## 0.2.1.1+#### Add+* Add colors to hspec-golden CLI tool.+ ## 0.2.1.0 #### Add * Instance for IO Golden type. Kudos to @dbalseiro
README.md view
@@ -1,5 +1,5 @@ # hspec-golden-[![Build Status](https://travis-ci.org/stackbuilders/hspec-golden.svg?branch=master)](https://travis-ci.org/stackbuilders/hspec-golden)+[![Build and Test](https://github.com/stackbuilders/hspec-golden/actions/workflows/build-and-test.yml/badge.svg?branch=main)](https://github.com/stackbuilders/hspec-golden/actions/workflows/build-and-test.yml) [![Hackage](https://img.shields.io/hackage/v/hspec-golden.svg)](http://hackage.haskell.org/package/hspec-golden)  ## Description Golden tests store the expected output in a separated file. Each time a golden test@@ -25,6 +25,15 @@ always have a unique name for your file. Example: `show 'myFunc == MyModule.myFunc`. Although, you can name it as you like. +You can write golden tests using `golden` helper:++```haskell+describe "myFunc" $+  golden "generates the right output with the right params" $+     let output = show $ myFunc params+       in return output+```+ In case your output isn't a `String` you can define your own `Golden` test using the `Golden` data type: @@ -48,10 +57,12 @@     failFirstTime = False   } -describe "myTextFunc" $-  it "generates the right output with the right params" $-     let textOutput = myTextFunc params-       in myGoldenTest (show 'myTextFunc) textOutput+spec :: Spec+spec =+  describe "myTextFunc" $+    it "generates the right output with the right params" $+       let textOutput = myTextFunc params+         in myGoldenTest (show 'myTextFunc) textOutput ```  ## Install CLI@@ -96,6 +107,47 @@ ``` $ hgold -u .myGoldenTest ```++## Contributors ✨++Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):++<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->+<!-- prettier-ignore-start -->+<!-- markdownlint-disable -->+<table>+  <tbody>+    <tr>+      <td align="center" valign="top" width="14.28%"><a href="https://cristhianmotoche.github.io/"><img src="https://avatars.githubusercontent.com/u/8370088?v=4?s=100" width="100px;" alt="Cristhian Motoche"/><br /><sub><b>Cristhian Motoche</b></sub></a><br /><a href="https://github.com/stackbuilders/hspec-golden/commits?author=CristhianMotoche" title="Code">💻</a></td>+      <td align="center" valign="top" width="14.28%"><a href="https://www.christian-wuensche.com/"><img src="https://avatars.githubusercontent.com/u/3807237?v=4?s=100" width="100px;" alt="Christian Wünsche (ehem Heyn)"/><br /><sub><b>Christian Wünsche (ehem Heyn)</b></sub></a><br /><a href="https://github.com/stackbuilders/hspec-golden/commits?author=christianwish" title="Code">💻</a></td>+      <td align="center" valign="top" width="14.28%"><a href="https://github.com/bitc"><img src="https://avatars.githubusercontent.com/u/996487?v=4?s=100" width="100px;" alt="Bit Connor"/><br /><sub><b>Bit Connor</b></sub></a><br /><a href="https://github.com/stackbuilders/hspec-golden/commits?author=bitc" title="Code">💻</a></td>+      <td align="center" valign="top" width="14.28%"><a href="https://dbalseiro.github.io/"><img src="https://avatars.githubusercontent.com/u/2053849?v=4?s=100" width="100px;" alt="Diego Balseiro"/><br /><sub><b>Diego Balseiro</b></sub></a><br /><a href="https://github.com/stackbuilders/hspec-golden/commits?author=dbalseiro" title="Code">💻</a></td>+      <td align="center" valign="top" width="14.28%"><a href="https://github.com/Jagl257"><img src="https://avatars.githubusercontent.com/u/27145248?v=4?s=100" width="100px;" alt="Jorge Guerra Landázuri"/><br /><sub><b>Jorge Guerra Landázuri</b></sub></a><br /><a href="https://github.com/stackbuilders/hspec-golden/commits?author=Jagl257" title="Code">💻</a></td>+      <td align="center" valign="top" width="14.28%"><a href="https://github.com/ChickenProp"><img src="https://avatars.githubusercontent.com/u/57271?v=4?s=100" width="100px;" alt="Phil Hazelden"/><br /><sub><b>Phil Hazelden</b></sub></a><br /><a href="https://github.com/stackbuilders/hspec-golden/commits?author=ChickenProp" title="Code">💻</a></td>+      <td align="center" valign="top" width="14.28%"><a href="http://alexvieth.wordpress.com/"><img src="https://avatars.githubusercontent.com/u/1420272?v=4?s=100" width="100px;" alt="Alexander Vieth"/><br /><sub><b>Alexander Vieth</b></sub></a><br /><a href="https://github.com/stackbuilders/hspec-golden/commits?author=avieth" title="Code">💻</a></td>+    </tr>+    <tr>+      <td align="center" valign="top" width="14.28%"><a href="https://github.com/guibou"><img src="https://avatars.githubusercontent.com/u/9705357?v=4?s=100" width="100px;" alt="Guillaume Bouchard"/><br /><sub><b>Guillaume Bouchard</b></sub></a><br /><a href="https://github.com/stackbuilders/hspec-golden/commits?author=guibou" title="Code">💻</a></td>+      <td align="center" valign="top" width="14.28%"><a href="https://github.com/fefi95"><img src="https://avatars.githubusercontent.com/u/12057338?v=4?s=100" width="100px;" alt="Stefani Castellanos"/><br /><sub><b>Stefani Castellanos</b></sub></a><br /><a href="https://github.com/stackbuilders/hspec-golden/commits?author=fefi95" title="Code">💻</a></td>+    </tr>+  </tbody>+  <tfoot>+    <tr>+      <td align="center" size="13px" colspan="7">+        <img src="https://raw.githubusercontent.com/all-contributors/all-contributors-cli/1b8533af435da9854653492b1327a23a4dbd0a10/assets/logo-small.svg">+          <a href="https://all-contributors.js.org/docs/en/bot/usage">Add your contributions</a>+        </img>+      </td>+    </tr>+  </tfoot>+</table>++<!-- markdownlint-restore -->+<!-- prettier-ignore-end -->++<!-- ALL-CONTRIBUTORS-LIST:END -->++This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!  ## License 
app/Main.hs view
@@ -1,10 +1,12 @@ module Main where +import           System.Console.ANSI import           Control.Monad         (forM_, when) import           Data.Version          (showVersion) import           Paths_hspec_golden    (version) import           Options.Applicative import           Data.Monoid ((<>))+import           GHC.IO (catch) import           System.Directory      (doesDirectoryExist, doesFileExist,                                         listDirectory, renameFile) import qualified Test.Hspec.Golden     as G@@ -14,14 +16,10 @@  -- CLI Params -data Params =-    Params-      { updateDir    :: FilePath -   --   , shouldUpdate :: Bool-      } deriving Show-  +newtype Params = Params { updateDir :: FilePath } deriving Show+ params :: Parser Params-params = Params +params = Params       <$> strOption           (long "update"           <> short 'u'@@ -31,18 +29,28 @@           <> help "The testing directory where you're dumping your results.")  versionOpt :: Parser (a->a)-versionOpt = infoOption (showVersion version) +versionOpt = infoOption (showVersion version)               (long "version"-              <> short 'v'  +              <> short 'v'               <> help "Show version")-             ---Update Files+withColor :: Color -> IO () -> IO ()+withColor color action = do+  setSGR [SetColor Foreground Dull color]+  action+  setSGR [Reset]++success, warning, failure :: IO () -> IO ()+success = withColor Green+warning = withColor Yellow+failure = withColor Red++-- Update golden files in the given directory updateGolden :: FilePath -> IO () updateGolden dir = do-  putStrLn "Replacing golden with actual..."+  putStrLn "Replacing golden with actual:"   go dir-  putStrLn "Finish..."+  success $ putStrLn "Finished!"  where   go dir = do     entries <- listDirectory dir@@ -59,9 +67,16 @@       goldenFilePath = testPath ++ "/golden"    in do      actualFileExist <- doesFileExist actualFilePath-     when actualFileExist (do-       putStrLn $ "  Replacing file: " ++ goldenFilePath ++ " with: " ++ actualFilePath-       renameFile actualFilePath goldenFilePath)+     when actualFileExist $ do+       putStr "  Replacing file: "+       warning $ putStr goldenFilePath+       putStr " with: "+       success $ putStrLn actualFilePath+       renameFile actualFilePath goldenFilePath `catch` handleErr+        where+          handleErr :: IOError -> IO ()+          handleErr e =+            failure $ putStr $ "Warning: Could not replace file due to error: " ++ show e   -- Main
hspec-golden.cabal view
@@ -1,11 +1,11 @@ cabal-version: 1.12 --- This file has been generated from package.yaml by hpack version 0.35.2.+-- This file has been generated from package.yaml by hpack version 0.36.0. -- -- see: https://github.com/sol/hpack  name:           hspec-golden-version:        0.2.1.0+version:        0.2.2.0 synopsis:       Golden tests for hspec description:    .                 Golden tests store the expected output in a separated file. Each time a golden test@@ -31,6 +31,8 @@ license:        MIT license-file:   LICENSE build-type:     Simple+tested-with:+    GHC==8.8, GHC==8.10, GHC==9.0 extra-source-files:     README.md     ChangeLog.md@@ -48,9 +50,9 @@       src   build-depends:       base >=4.6 && <5-    , directory+    , directory >=1.3.6 && <1.4     , filepath >=1.0 && <2.0-    , hspec-core >=2.5 && <3.0+    , hspec-core >=2.10 && <3.0   default-language: Haskell2010  executable hgold@@ -61,10 +63,11 @@       app   ghc-options: -threaded -rtsopts -with-rtsopts=-N   build-depends:-      base >=4.6 && <5+      ansi-terminal >=1.0 && <2.0+    , base >=4.6 && <5     , directory >=1.2.5.0     , hspec-golden-    , optparse-applicative+    , optparse-applicative >=0.18.1 && <0.19   default-language: Haskell2010  test-suite hspec-golden-test
src/Test/Hspec/Golden.hs view
@@ -21,14 +21,19 @@ module Test.Hspec.Golden   ( Golden(..)   , defaultGolden+  , golden   )   where +import           Control.Monad.IO.Class (MonadIO (liftIO)) import           Data.IORef-import           System.Directory     (createDirectoryIfMissing, doesFileExist)-import           System.FilePath      (takeDirectory, (</>))-import           Test.Hspec.Core.Spec (Example (..), FailureReason (..),-                                       Result (..), ResultStatus (..))+import           Data.List              (intercalate)+import           System.Directory       (createDirectoryIfMissing,+                                         doesFileExist)+import           System.FilePath        (takeDirectory, (</>))+import           Test.Hspec.Core.Spec   (Example (..), FailureReason (..),+                                         Result (..), ResultStatus (..), Spec,+                                         SpecWith, getSpecDescriptionPath, it)   -- | Golden tests parameters@@ -99,7 +104,7 @@ fromGoldenResult FirstExecutionFail =   Result "First time execution. Golden file created."          (Failure Nothing (Reason "Golden file did not exist and was created. Failed because failFirstTime is set to True"))-fromGoldenResult (MissmatchOutput expected actual) =+fromGoldenResult (MismatchOutput expected actual) =   Result "Files golden and actual not match"          (Failure Nothing (ExpectedButGot Nothing expected actual)) @@ -127,7 +132,7 @@ -- | Possible results from a golden test execution  data GoldenResult =-   MissmatchOutput String String+   MismatchOutput String String    | SameOutput    | FirstExecutionSucceed    | FirstExecutionFail@@ -161,4 +166,22 @@            if contentGolden == output              then return SameOutput-             else return $ MissmatchOutput (encodePretty contentGolden) (encodePretty output)+             else return $ MismatchOutput (encodePretty contentGolden) (encodePretty output)+++-- | A helper function to create a golden test.+--+-- @+--  describe "function" $+--    golden "some name" $+--      return content+-- @++golden+  :: String     -- ^ Test description+  -> IO String  -- ^ Content (@return content@ for pure functions)+  -> Spec+golden description runAction = do+  path <- (++ words description) <$> getSpecDescriptionPath+  it description $+    defaultGolden (intercalate "-" path) <$> runAction
test/Test/Hspec/GoldenSpec.hs view
@@ -1,6 +1,6 @@ module Test.Hspec.GoldenSpec (spec) where -import           Control.Monad          (void)+import           Control.Monad          (void, when)  import           Test.Hspec import qualified Test.Hspec.Core.Runner as H@@ -24,12 +24,20 @@  fixtureTest :: String -> H.Spec fixtureTest content =-  H.describe "id" $-    H.it "should work" $+  describe "id" $+    it "should work" $       defaultGolden fixtureTestName content +fixtureGoldenTest :: String -> H.Spec+fixtureGoldenTest content =+  describe "id" $+    golden "golden sample file" $+      return content+ removeFixtures :: IO ()-removeFixtures = removeDirectoryRecursive goldenTestDir+removeFixtures = do+  exists <- doesDirectoryExist ".golden"+  when exists $ removeDirectoryRecursive ".golden"  runSpec :: H.Spec -> IO [String] runSpec = captureLines . H.hspecResult@@ -59,7 +67,7 @@            actualFileContent <- readFile actualFilePath            actualFileContent `shouldBe` fixtureUpdatedContent -        it "shouldn't overide the `golden` file" $ do+        it "shouldn't override the `golden` file" $ do            void $ runSpec $ fixtureTest fixtureContent            void $ runSpec $ fixtureTest fixtureUpdatedContent            goldenFileContent <- readFile goldenFilePath@@ -78,3 +86,10 @@            void $ runSpec $ fixtureTest fixtureContent            goldenFileContent <- readFile goldenFilePath            goldenFileContent `shouldBe` fixtureContent++    describe "golden" $+      context "given some input" $+        it "creates file with separated dashes" $ do+          void $ runSpec $ fixtureGoldenTest fixtureContent+          goldenFile <- readFile ".golden/id-golden-sample-file/golden"+          goldenFile `shouldBe` fixtureContent