packages feed

escaped 1.0.0.0 → 1.1.0.0

raw patch · 8 files changed

+412/−347 lines, 8 filesdep ~QuickCheckdep ~basedep ~doctestsetup-changedPVP ok

version bump matches the API change (PVP)

Dependency ranges changed: QuickCheck, base, doctest, hspec, quickcheck-instances, quickcheck-properties, text, unix

API changes (from Hackage documentation)

Files

README.md view
@@ -91,8 +91,6 @@ stack build --pedantic test ``` -See also the [`Makefile`](./Makefile).- ---  [CHANGELOG](./CHANGELOG.md) | [LICENSE](./LICENSE)
− Setup.hs
@@ -1,2 +0,0 @@-import Distribution.Simple-main = defaultMain
app/Main.hs view
@@ -1,62 +1,64 @@-{-# LANGUAGE OverloadedStrings #-} module Main (main) where -import Control.Monad (forM_)-import Data.Semigroup ((<>))-import qualified Data.Text as T+import Prelude++import Data.Foldable (for_)+import Data.Text (pack)+import Data.Text qualified as T import Data.Text.Escaped-import qualified Data.Text.IO as T+import Data.Text.IO qualified as T  main :: IO () main = do-    forM_ simpleColors $ \(f, b) -> do-        let label = T.pack $ show f <> " on " <> show b+  for_ simpleColors $ \(f, b) -> do+    let label = pack $ show f <> " on " <> show b -        T.putStrLn-            $ render-            $ "This text is "-            <> FG f-            <> BG b-            <> Plain label-            <> Reset-            <> "."+    T.putStrLn $+      render $+        "This text is "+          <> FG f+          <> BG b+          <> Plain label+          <> Reset+          <> "." -    forM_ simpleEscapes $ \e -> do-        let label = T.pack $ show e+  for_ simpleEscapes $ \e -> do+    let label = pack $ show e -        T.putStrLn-            $ render-            $ "This text is "-            <> e-            <> Plain label-            <> Reset-            <> "."+    T.putStrLn $+      render $+        "This text is "+          <> e+          <> Plain label+          <> Reset+          <> "." -    forM_ [0 .. 255] $ \n -> do-        let label = Plain $ T.center 5 ' ' $ T.pack $ show n-            escaped = render $ FG White <> BG (Custom n) <> label <> Reset+  for_ [0 .. 255] $ \n -> do+    let+      label = Plain $ T.center 5 ' ' $ pack $ show n+      escaped = render $ FG White <> BG (Custom n) <> label <> Reset -        if (n + 1) `mod` 8 == 0 then T.putStrLn escaped else T.putStr escaped+    if (n + 1) `mod` 8 == 0 then T.putStrLn escaped else T.putStr escaped  simpleColors :: [(Color, Color)] simpleColors =-    [ (Blue, Default)-    , (Cyan, Default)-    , (DarkGray, Default)-    , (Green, Default)-    , (LightBlue, Default)-    , (LightCyan, Default)-    , (LightGray, Default)-    , (LightGreen, Default)-    , (LightMagenta, Default)-    , (LightRed, Default)-    , (LightYellow, Default)-    , (Magenta, Default)-    , (Red, Default)-    , (Yellow, Default)-    , (White, Black)-    , (Black, White)-    ]+  [ (Blue, Default)+  , (Cyan, Default)+  , (DarkGray, Default)+  , (Green, Default)+  , (LightBlue, Default)+  , (LightCyan, Default)+  , (LightGray, Default)+  , (LightGreen, Default)+  , (LightMagenta, Default)+  , (LightRed, Default)+  , (LightYellow, Default)+  , (Magenta, Default)+  , (Red, Default)+  , (Yellow, Default)+  , (White, Black)+  , (Black, White)+  ]  simpleEscapes :: [Escaped] simpleEscapes = [Bold, Dim, Underlined, Blink, Reverse, Hidden]
doctest/Main.hs view
@@ -1,6 +1,15 @@ module Main (main) where +import Prelude+ import Test.DocTest  main :: IO ()-main = doctest ["-XOverloadedStrings", "src"]+main =+  doctest+    [ "-XDerivingStrategies"+    , "-XImportQualifiedPost"+    , "-XLambdaCase"+    , "-XOverloadedStrings"+    , "src"+    ]
escaped.cabal view
@@ -1,87 +1,144 @@-cabal-version: 1.12---- This file has been generated from package.yaml by hpack version 0.31.0.------ see: https://github.com/sol/hpack------ hash: 5730e4ee8bb5cfa0d5c8c39f5c26a891cfec88419d74f15fc0e4fe7e75f69ed1--name:           escaped-version:        1.0.0.0-synopsis:       Produce Text with terminal escape sequences-description:    See README.md-category:       Text-homepage:       https://github.com/pbrisbin/escaped#readme-bug-reports:    https://github.com/pbrisbin/escaped/issues-author:         Patrick Brisbin-maintainer:     pbrisbin@gmail.com-copyright:      2018 Patrick Brisbin-license:        MIT-license-file:   LICENSE-build-type:     Simple-extra-source-files:-    CHANGELOG.md+cabal-version:   1.18+name:            escaped+version:         1.1.0.0+license:         MIT+license-file:    LICENSE+copyright:       2018 Patrick Brisbin+maintainer:      pbrisbin@gmail.com+author:          Patrick Brisbin+homepage:        https://github.com/pbrisbin/escaped#readme+bug-reports:     https://github.com/pbrisbin/escaped/issues+synopsis:        Produce Text with terminal escape sequences+description:     See README.md+category:        Text+build-type:      Simple+extra-doc-files:     README.md+    CHANGELOG.md  source-repository head-  type: git-  location: https://github.com/pbrisbin/escaped+    type:     git+    location: https://github.com/pbrisbin/escaped  library-  hs-source-dirs:-      src-  ghc-options: -Wall-  build-depends:-      QuickCheck-    , base >=4.7 && <5-    , quickcheck-instances-    , text-    , unix-  exposed-modules:-      Data.Text.Escaped-  other-modules:-      Paths_escaped-  default-language: Haskell2010+    exposed-modules:    Data.Text.Escaped+    hs-source-dirs:     src+    other-modules:      Paths_escaped+    default-language:   Haskell2010+    default-extensions:+        DerivingStrategies ImportQualifiedPost LambdaCase NoImplicitPrelude+        OverloadedStrings +    ghc-options:+        -fignore-optim-changes -fwrite-ide-info -Weverything+        -Wno-all-missed-specialisations -Wno-missed-specialisations+        -Wno-missing-import-lists -Wno-missing-local-signatures+        -Wno-missing-safe-haskell-mode -Wno-monomorphism-restriction+        -Wno-prepositive-qualified-module -Wno-safe -Wno-unsafe++    build-depends:+        QuickCheck >=2.14.2,+        base >=4 && <5,+        quickcheck-instances >=0.3.25.2,+        text >=1.2.4.1,+        unix >=2.7.2.2++    if impl(ghc >=9.8)+        ghc-options:+            -Wno-missing-role-annotations -Wno-missing-poly-kind-signatures++    if impl(ghc >=9.2)+        ghc-options: -Wno-missing-kind-signatures+ executable escaped-example-  main-is: Main.hs-  hs-source-dirs:-      app-  ghc-options: -Wall -threaded -rtsopts -with-rtsopts=-N-  build-depends:-      base >=4.7 && <5-    , escaped-    , text-  other-modules:-      Paths_escaped-  default-language: Haskell2010+    main-is:            Main.hs+    hs-source-dirs:     app+    other-modules:      Paths_escaped+    default-language:   Haskell2010+    default-extensions:+        DerivingStrategies ImportQualifiedPost LambdaCase NoImplicitPrelude+        OverloadedStrings +    ghc-options:+        -fignore-optim-changes -fwrite-ide-info -Weverything+        -Wno-all-missed-specialisations -Wno-missed-specialisations+        -Wno-missing-import-lists -Wno-missing-local-signatures+        -Wno-missing-safe-haskell-mode -Wno-monomorphism-restriction+        -Wno-prepositive-qualified-module -Wno-safe -Wno-unsafe -threaded+        -rtsopts -with-rtsopts=-N++    build-depends:+        base >=4 && <5,+        escaped,+        text >=1.2.4.1++    if impl(ghc >=9.8)+        ghc-options:+            -Wno-missing-role-annotations -Wno-missing-poly-kind-signatures++    if impl(ghc >=9.2)+        ghc-options: -Wno-missing-kind-signatures+ test-suite doctest-  type: exitcode-stdio-1.0-  main-is: Main.hs-  hs-source-dirs:-      doctest-  ghc-options: -Wall -threaded -rtsopts -with-rtsopts=-N-  build-depends:-      base >=4.7 && <5-    , doctest-  other-modules:-      Paths_escaped-  default-language: Haskell2010+    type:               exitcode-stdio-1.0+    main-is:            Main.hs+    hs-source-dirs:     doctest+    other-modules:      Paths_escaped+    default-language:   Haskell2010+    default-extensions:+        DerivingStrategies ImportQualifiedPost LambdaCase NoImplicitPrelude+        OverloadedStrings +    ghc-options:+        -fignore-optim-changes -fwrite-ide-info -Weverything+        -Wno-all-missed-specialisations -Wno-missed-specialisations+        -Wno-missing-import-lists -Wno-missing-local-signatures+        -Wno-missing-safe-haskell-mode -Wno-monomorphism-restriction+        -Wno-prepositive-qualified-module -Wno-safe -Wno-unsafe -threaded+        -rtsopts -with-rtsopts=-N++    build-depends:+        base >=4 && <5,+        doctest >=0.17++    if impl(ghc >=9.8)+        ghc-options:+            -Wno-missing-role-annotations -Wno-missing-poly-kind-signatures++    if impl(ghc >=9.2)+        ghc-options: -Wno-missing-kind-signatures+ test-suite hspec-  type: exitcode-stdio-1.0-  main-is: Spec.hs-  hs-source-dirs:-      test-  ghc-options: -Wall -threaded -rtsopts -with-rtsopts=-N-  build-depends:-      QuickCheck-    , base >=4.7 && <5-    , escaped-    , hspec-    , quickcheck-properties-  other-modules:-      Data.Text.EscapedSpec-      Paths_escaped-  default-language: Haskell2010+    type:               exitcode-stdio-1.0+    main-is:            Spec.hs+    hs-source-dirs:     test+    other-modules:+        Data.Text.EscapedSpec+        Paths_escaped++    default-language:   Haskell2010+    default-extensions:+        DerivingStrategies ImportQualifiedPost LambdaCase NoImplicitPrelude+        OverloadedStrings++    ghc-options:+        -fignore-optim-changes -fwrite-ide-info -Weverything+        -Wno-all-missed-specialisations -Wno-missed-specialisations+        -Wno-missing-import-lists -Wno-missing-local-signatures+        -Wno-missing-safe-haskell-mode -Wno-monomorphism-restriction+        -Wno-prepositive-qualified-module -Wno-safe -Wno-unsafe -threaded+        -rtsopts -with-rtsopts=-N++    build-depends:+        QuickCheck >=2.14.2,+        base >=4 && <5,+        escaped,+        hspec >=2.7.10,+        quickcheck-properties >=0.1++    if impl(ghc >=9.8)+        ghc-options:+            -Wno-missing-role-annotations -Wno-missing-poly-kind-signatures++    if impl(ghc >=9.2)+        ghc-options: -Wno-missing-kind-signatures
src/Data/Text/Escaped.hs view
@@ -1,47 +1,47 @@-{-# LANGUAGE OverloadedStrings #-} module Data.Text.Escaped-    ( Escaped-        ( Plain-        , Reset-        , Bold-        , Dim-        , Underlined-        , Blink-        , Reverse-        , Hidden-        , FG-        , BG-        )-    , Color(..)-    , black-    , blue-    , cyan-    , darkGray-    , green-    , lightBlue-    , lightCyan-    , lightGray-    , lightGreen-    , lightMagenta-    , lightRed-    , lightYellow-    , magenta-    , red-    , white-    , yellow-    , fg-    , bg-    , esc-    , render-    , plain-    , visibleLength-    , terminalRenderer-    ) where+  ( Escaped+      ( Plain+      , Reset+      , Bold+      , Dim+      , Underlined+      , Blink+      , Reverse+      , Hidden+      , FG+      , BG+      )+  , Color (..)+  , black+  , blue+  , cyan+  , darkGray+  , green+  , lightBlue+  , lightCyan+  , lightGray+  , lightGreen+  , lightMagenta+  , lightRed+  , lightYellow+  , magenta+  , red+  , white+  , yellow+  , fg+  , bg+  , esc+  , render+  , plain+  , visibleLength+  , terminalRenderer+  ) where -import Data.Semigroup (Semigroup(..))-import Data.String (IsString(..))-import Data.Text (Text)-import qualified Data.Text as T+import Prelude++import Data.String (IsString (..))+import Data.Text (Text, pack)+import Data.Text qualified as T import System.Posix.IO (stdOutput) import System.Posix.Terminal (queryTerminal) import Test.QuickCheck@@ -49,99 +49,99 @@  -- | Supported colors data Color-    = Default-    | Custom Int-    | Black-    | Blue-    | Cyan-    | DarkGray-    | Green-    | LightBlue-    | LightCyan-    | LightGray-    | LightGreen-    | LightMagenta-    | LightRed-    | LightYellow-    | Magenta-    | Red-    | White-    | Yellow-    deriving (Eq, Show)+  = Default+  | Custom Int+  | Black+  | Blue+  | Cyan+  | DarkGray+  | Green+  | LightBlue+  | LightCyan+  | LightGray+  | LightGreen+  | LightMagenta+  | LightRed+  | LightYellow+  | Magenta+  | Red+  | White+  | Yellow+  deriving stock (Eq, Show)  instance Arbitrary Color where-    -- Too bad @Custom@ makes arbitraryBoundedEnum not useful-    arbitrary = oneof-        [ pure Default-        , Custom <$> arbitrary-        , pure Black-        , pure Blue-        , pure Cyan-        , pure DarkGray-        , pure Green-        , pure LightBlue-        , pure LightCyan-        , pure LightGray-        , pure LightGreen-        , pure LightMagenta-        , pure LightRed-        , pure LightYellow-        , pure Magenta-        , pure Red-        , pure White-        , pure Yellow-        ]+  -- Too bad @Custom@ makes arbitraryBoundedEnum not useful+  arbitrary =+    oneof+      [ pure Default+      , Custom <$> arbitrary+      , pure Black+      , pure Blue+      , pure Cyan+      , pure DarkGray+      , pure Green+      , pure LightBlue+      , pure LightCyan+      , pure LightGray+      , pure LightGreen+      , pure LightMagenta+      , pure LightRed+      , pure LightYellow+      , pure Magenta+      , pure Red+      , pure White+      , pure Yellow+      ]  -- | Bits of escaped text data Escaped-    = Plain Text-    | Reset-    | Bold-    | Dim-    | Underlined-    | Blink-    | Reverse-    | Hidden-    | FG Color-    | BG Color-    | Many [Escaped]-    deriving (Eq, Show)+  = Plain Text+  | Reset+  | Bold+  | Dim+  | Underlined+  | Blink+  | Reverse+  | Hidden+  | FG Color+  | BG Color+  | Many [Escaped]+  deriving stock (Eq, Show)  instance Arbitrary Escaped where-    -- Avoid invalid Many-of-Many nesting, which triggers an infinite loop. Such-    -- a value is impossible to construct because we don't export the Many-    -- constructor.-    arbitrary = oneof $ chunks <> [Many <$> listOf1 (oneof chunks)]-      where-        chunks =-            [ Plain <$> arbitrary-            , pure Reset-            , pure Bold-            , pure Dim-            , pure Underlined-            , pure Blink-            , pure Reverse-            , pure Hidden-            , FG <$> arbitrary-            , BG <$> arbitrary-            ]+  -- Avoid invalid Many-of-Many nesting, which triggers an infinite loop. Such+  -- a value is impossible to construct because we don't export the Many+  -- constructor.+  arbitrary = oneof $ chunks <> [Many <$> listOf1 (oneof chunks)]+   where+    chunks =+      [ Plain <$> arbitrary+      , pure Reset+      , pure Bold+      , pure Dim+      , pure Underlined+      , pure Blink+      , pure Reverse+      , pure Hidden+      , FG <$> arbitrary+      , BG <$> arbitrary+      ]  instance IsString Escaped where-    fromString = Plain . T.pack+  fromString = Plain . pack  instance Semigroup Escaped where-    -- A bit explicit, but ensures identity works-    x <> (Plain t) | T.null t = x-    (Plain t) <> y | T.null t = y--    (Many a) <> (Many b) = Many $ a <> b-    (Many a) <> b = Many $ a <> [b]-    a <> (Many b) = Many $ a:b-    a <> b = Many [a, b]+  -- A bit explicit, but ensures identity works+  x <> (Plain t) | T.null t = x+  (Plain t) <> y | T.null t = y+  (Many a) <> (Many b) = Many $ a <> b+  (Many a) <> b = Many $ a <> [b]+  a <> (Many b) = Many $ a : b+  a <> b = Many [a, b]  instance Monoid Escaped where-    mempty = Plain ""-    mappend = (<>)+  mempty = Plain ""+  mappend = (<>)  -- | Render an @'Escaped'@ to actually-escaped @'Text'@ --@@ -161,19 +161,19 @@ -- -- >>> render $ "Some " <> fg (Custom 212) "color 212" <> " text." -- "Some \ESC[38;5;212mcolor 212\ESC[0m text."--- render :: Escaped -> Text-render (Plain t) = t-render (Many es) = T.concat $ map render es-render Reset = "\ESC[0m"-render Bold = "\ESC[1m"-render Dim = "\ESC[2m"-render Underlined = "\ESC[3m"-render Blink = "\ESC[5m"-render Reverse = "\ESC[7m"-render Hidden = "\ESC[8m"-render (FG c) = "\ESC[" <> fgColorCode c <> "m"-render (BG c) = "\ESC[" <> bgColorCode c <> "m"+render = \case+  Plain t -> t+  Many es -> mconcat $ map render es+  Reset -> "\ESC[0m"+  Bold -> "\ESC[1m"+  Dim -> "\ESC[2m"+  Underlined -> "\ESC[3m"+  Blink -> "\ESC[5m"+  Reverse -> "\ESC[7m"+  Hidden -> "\ESC[8m"+  FG c -> "\ESC[" <> fgColorCode c <> "m"+  BG c -> "\ESC[" <> bgColorCode c <> "m"  -- | Render only the @'Text'@ parts --@@ -184,11 +184,11 @@ -- -- >>> plain $ "Some " <> FG Red <> "red" <> Reset <> " text." -- "Some red text."--- plain :: Escaped -> Text-plain (Plain t) = t-plain (Many es) = T.concat $ map plain es-plain _ = ""+plain = \case+  Plain t -> t+  Many es -> mconcat $ map plain es+  _ -> ""  black :: Escaped -> Escaped black = fg Black@@ -242,7 +242,6 @@ -- -- >>> fg Red "red" -- Many [FG Red,Plain "red",Reset]--- fg :: Color -> Escaped -> Escaped fg = esc . FG @@ -250,7 +249,6 @@ -- -- >>> bg Red "red" -- Many [BG Red,Plain "red",Reset]--- bg :: Color -> Escaped -> Escaped bg = esc . BG @@ -258,15 +256,15 @@ -- -- >>> esc (FG Red) "red" -- Many [FG Red,Plain "red",Reset]--- esc :: Escaped -> Escaped -> Escaped esc a b = a <> b <> Reset  -- | Calculate the /visible/ length of an @'Escaped'@ visibleLength :: Escaped -> Int-visibleLength (Plain t) = T.length t-visibleLength (Many es) = sum $ map visibleLength es-visibleLength _ = 0+visibleLength = \case+  Plain t -> T.length t+  Many es -> sum $ map visibleLength es+  _ -> 0  -- | An @'IO'@ action to produce the appropriate renderer for a terminal --@@ -275,48 +273,49 @@ -- >>> r <- terminalRenderer -- >>> print $ r $ red "red text" -- "red text"--- terminalRenderer :: IO (Escaped -> Text) terminalRenderer = do-    istty <- queryTerminal stdOutput-    return $ if istty then render else plain+  istty <- queryTerminal stdOutput+  return $ if istty then render else plain  fgColorCode :: Color -> Text-fgColorCode Default = "39"-fgColorCode (Custom n) = "38;5;" <> T.pack (show n)-fgColorCode Black = "30"-fgColorCode Blue = "34"-fgColorCode Cyan = "36"-fgColorCode DarkGray = "90"-fgColorCode Green = "32"-fgColorCode LightBlue = "94"-fgColorCode LightCyan = "96"-fgColorCode LightGray = "37"-fgColorCode LightGreen = "92"-fgColorCode LightMagenta = "95"-fgColorCode LightRed = "91"-fgColorCode LightYellow = "93"-fgColorCode Magenta = "35"-fgColorCode Red = "31"-fgColorCode White = "97"-fgColorCode Yellow = "33"+fgColorCode = \case+  Default -> "39"+  Custom n -> "38;5;" <> pack (show n)+  Black -> "30"+  Blue -> "34"+  Cyan -> "36"+  DarkGray -> "90"+  Green -> "32"+  LightBlue -> "94"+  LightCyan -> "96"+  LightGray -> "37"+  LightGreen -> "92"+  LightMagenta -> "95"+  LightRed -> "91"+  LightYellow -> "93"+  Magenta -> "35"+  Red -> "31"+  White -> "97"+  Yellow -> "33"  bgColorCode :: Color -> Text-bgColorCode Default = "49"-bgColorCode (Custom n) = "48;5;" <> T.pack (show n)-bgColorCode Black = "40"-bgColorCode Blue = "44"-bgColorCode Cyan = "46"-bgColorCode DarkGray = "100"-bgColorCode Green = "42"-bgColorCode LightBlue = "104"-bgColorCode LightCyan = "106"-bgColorCode LightGray = "100"-bgColorCode LightGreen = "102"-bgColorCode LightMagenta = "105"-bgColorCode LightRed = "101"-bgColorCode LightYellow = "103"-bgColorCode Magenta = "45"-bgColorCode Red = "41"-bgColorCode White = "107"-bgColorCode Yellow = "103"+bgColorCode = \case+  Default -> "49"+  Custom n -> "48;5;" <> pack (show n)+  Black -> "40"+  Blue -> "44"+  Cyan -> "46"+  DarkGray -> "100"+  Green -> "42"+  LightBlue -> "104"+  LightCyan -> "106"+  LightGray -> "100"+  LightGreen -> "102"+  LightMagenta -> "105"+  LightRed -> "101"+  LightYellow -> "103"+  Magenta -> "45"+  Red -> "41"+  White -> "107"+  Yellow -> "103"
test/Data/Text/EscapedSpec.hs view
@@ -1,50 +1,51 @@-{-# LANGUAGE OverloadedStrings #-}- module Data.Text.EscapedSpec-    ( spec-    ) where+  ( spec+  ) where -import Control.Monad (forM_)-import Data.Semigroup ((<>))+import Prelude++import Data.Foldable (for_) import Data.Text.Escaped import Test.Hspec import Test.QuickCheck import Test.QuickCheck.Property.Monoid --- brittany-disable-next-binding- spec :: Spec spec = do-    describe "Escaped" $ do-        it "is a Monoid" $ property-            $ eq $ prop_Monoid (T :: T Escaped)+  describe "Escaped" $ do+    it "is a Monoid" $+      property $+        eq $+          prop_Monoid (T :: T Escaped) -    describe "visibleLength" $ do-        it "calculates the visible length of escaped text" $ do-            let l1 = visibleLength "Some text."-                l2 = visibleLength $ FG Red <> "Some text" <> Reset <> "."+  describe "visibleLength" $ do+    it "calculates the visible length of escaped text" $ do+      let+        l1 = visibleLength "Some text."+        l2 = visibleLength $ FG Red <> "Some text" <> Reset <> "." -            l1 `shouldBe` 10-            l2 `shouldBe` 10+      l1 `shouldBe` 10+      l2 `shouldBe` 10 -    describe "foreground color helpers" $ do-        forM_-            [ (black, Black)-            , (blue, Blue)-            , (cyan, Cyan)-            , (darkGray, DarkGray)-            , (green, Green)-            , (lightBlue, LightBlue)-            , (lightCyan, LightCyan)-            , (lightGray, LightGray)-            , (lightGreen, LightGreen)-            , (lightMagenta, LightMagenta)-            , (lightRed, LightRed)-            , (lightYellow, LightYellow)-            , (magenta, Magenta)-            , (red, Red)-            , (white, White)-            , (yellow, Yellow)-            ]-            $ \(h, c) -> it ("uses the correct color for " <> show c) $-                h "hi" `shouldBe` FG c <> Plain "hi" <> Reset+  describe "foreground color helpers" $ do+    for_+      [ (black, Black)+      , (blue, Blue)+      , (cyan, Cyan)+      , (darkGray, DarkGray)+      , (green, Green)+      , (lightBlue, LightBlue)+      , (lightCyan, LightCyan)+      , (lightGray, LightGray)+      , (lightGreen, LightGreen)+      , (lightMagenta, LightMagenta)+      , (lightRed, LightRed)+      , (lightYellow, LightYellow)+      , (magenta, Magenta)+      , (red, Red)+      , (white, White)+      , (yellow, Yellow)+      ]+      $ \(h, c) ->+        it ("uses the correct color for " <> show c) $+          h "hi" `shouldBe` FG c <> Plain "hi" <> Reset
test/Spec.hs view
@@ -1,1 +1,2 @@ {-# OPTIONS_GHC -F -pgmF hspec-discover #-}+{-# OPTIONS_GHC -Wno-missing-export-lists #-}