├── cabal.project ├── Setup.hs ├── tests ├── Spec.hs ├── Spec │ ├── Control │ │ ├── Monad │ │ │ └── STSpec.hs │ │ ├── ApplicativeSpec.hs │ │ ├── ConcurrentSpec.hs │ │ └── ExceptionSpec.hs │ ├── Data │ │ ├── RatioSpec.hs │ │ ├── ComplexSpec.hs │ │ ├── DynamicSpec.hs │ │ ├── BoolSpec.hs │ │ ├── ProxySpec.hs │ │ ├── List │ │ │ └── NonEmptySpec.hs │ │ ├── Functor │ │ │ ├── IdentitySpec.hs │ │ │ ├── SumSpec.hs │ │ │ ├── ComposeSpec.hs │ │ │ └── ProductSpec.hs │ │ ├── EitherSpec.hs │ │ ├── MaybeSpec.hs │ │ ├── Type │ │ │ ├── CoercionSpec.hs │ │ │ └── EqualitySpec.hs │ │ ├── VersionSpec.hs │ │ ├── OrdSpec.hs │ │ ├── Array │ │ │ └── ByteSpec.hs │ │ ├── CharSpec.hs │ │ ├── DataSpec.hs │ │ ├── ArraySpec.hs │ │ ├── ByteStringSpec.hs │ │ ├── SemigroupSpec.hs │ │ ├── ListSpec.hs │ │ ├── TextSpec.hs │ │ ├── FixedSpec.hs │ │ ├── MonoidSpec.hs │ │ ├── TypeableSpec.hs │ │ ├── IntegralSpec.hs │ │ └── FloatingSpec.hs │ ├── System │ │ ├── ExitSpec.hs │ │ └── IOSpec.hs │ ├── Numeric │ │ └── NaturalSpec.hs │ ├── FunctionsSpec.hs │ ├── GHC │ │ ├── StaticPtrSpec.hs │ │ ├── FingerprintSpec.hs │ │ ├── StackSpec.hs │ │ ├── StatsSpec.hs │ │ ├── Conc │ │ │ └── WindowsSpec.hs │ │ ├── EventSpec.hs │ │ ├── TypeLitsSpec.hs │ │ └── RTS │ │ │ └── FlagsSpec.hs │ ├── Derived │ │ ├── RankNTypesSpec.hs │ │ ├── DatatypeContextsSpec.hs │ │ ├── ExistentialQuantificationSpec.hs │ │ ├── TypeFamiliesSpec.hs │ │ ├── TypeSynonymsSpec.hs │ │ ├── RecordsSpec.hs │ │ ├── InfixSpec.hs │ │ ├── MagicHashSpec.hs │ │ ├── DataFamiliesSpec.hs │ │ └── PolyKindsSpec.hs │ ├── Text │ │ └── ReadSpec.hs │ ├── OptionsSpec.hs │ ├── GenericSpec.hs │ ├── Foreign │ │ ├── PtrSpec.hs │ │ └── C │ │ │ └── TypesSpec.hs │ ├── BuilderSpec.hs │ └── FromStringTextShowSpec.hs ├── Instances │ ├── Data │ │ ├── Char.hs │ │ ├── Ord.hs │ │ ├── Dynamic.hs │ │ ├── Semigroup.hs │ │ ├── Monoid.hs │ │ ├── Type │ │ │ ├── Coercion.hs │ │ │ └── Equality.hs │ │ ├── Floating.hs │ │ ├── Data.hs │ │ ├── Text.hs │ │ └── Tuple.hs │ ├── Control │ │ ├── Monad │ │ │ └── ST.hs │ │ └── Concurrent.hs │ ├── Foreign │ │ ├── C │ │ │ └── Types.hs │ │ └── Ptr.hs │ ├── Options.hs │ ├── Utils.hs │ ├── GHC │ │ ├── StaticPtr.hs │ │ ├── Conc │ │ │ └── Windows.hs │ │ ├── Fingerprint.hs │ │ ├── Stats.hs │ │ ├── Event.hs │ │ ├── Stack.hs │ │ ├── TypeLits.hs │ │ └── Generics.hs │ ├── Text │ │ └── Read.hs │ ├── FromStringTextShow.hs │ ├── System │ │ ├── IO.hs │ │ └── Posix │ │ │ └── Types.hs │ └── Generic.hs └── Derived │ ├── TypeFamilies.hs │ ├── Records.hs │ ├── TypeSynonyms.hs │ ├── DatatypeContexts.hs │ └── RankNTypes.hs ├── cabal.haskell-ci ├── .gitignore ├── src ├── TextShow │ ├── Data │ │ ├── Bool.hs │ │ ├── Void.hs │ │ ├── Maybe.hs │ │ ├── Either.hs │ │ ├── List │ │ │ └── NonEmpty.hs │ │ ├── Dynamic.hs │ │ ├── Functor │ │ │ ├── Sum.hs │ │ │ ├── Product.hs │ │ │ ├── Identity.hs │ │ │ └── Compose.hs │ │ ├── Type │ │ │ ├── Coercion.hs │ │ │ └── Equality.hs │ │ ├── List.hs │ │ ├── Data.hs │ │ ├── Typeable │ │ │ └── Utils.hs │ │ ├── Proxy.hs │ │ ├── Ratio.hs │ │ ├── Ord.hs │ │ ├── Semigroup.hs │ │ ├── Version.hs │ │ ├── Complex.hs │ │ ├── Monoid.hs │ │ ├── Array │ │ │ └── Byte.hs │ │ ├── Array.hs │ │ ├── Fixed.hs │ │ └── Text.hs │ ├── System │ │ ├── Exit.hs │ │ └── IO.hs │ ├── GHC │ │ ├── StaticPtr.hs │ │ ├── Conc │ │ │ └── Windows.hs │ │ ├── Stack.hs │ │ ├── Stats.hs │ │ ├── Fingerprint.hs │ │ ├── Event.hs │ │ ├── TypeLits.hs │ │ └── RTS │ │ │ └── Flags.hs │ ├── TH.hs │ ├── Text │ │ └── Read.hs │ ├── Functions.hs │ ├── Control │ │ ├── Monad │ │ │ └── ST.hs │ │ ├── Applicative.hs │ │ └── Concurrent.hs │ ├── Numeric │ │ └── Natural.hs │ ├── Debug │ │ └── Trace │ │ │ ├── Generic.hs │ │ │ └── TH.hs │ ├── Options.hs │ ├── Foreign │ │ ├── C │ │ │ └── Types.hs │ │ └── Ptr.hs │ ├── Instances.hs │ └── Utils.hs └── TextShow.hs ├── appveyor.yml ├── LICENSE ├── README.md └── shared └── TextShow └── TH └── Names.hs /cabal.project: -------------------------------------------------------------------------------- 1 | packages: . 2 | -------------------------------------------------------------------------------- /Setup.hs: -------------------------------------------------------------------------------- 1 | import Distribution.Simple 2 | main = defaultMain 3 | -------------------------------------------------------------------------------- /tests/Spec.hs: -------------------------------------------------------------------------------- 1 | {-# OPTIONS_GHC -F -pgmF hspec-discover #-} 2 | -------------------------------------------------------------------------------- /cabal.haskell-ci: -------------------------------------------------------------------------------- 1 | distribution: jammy 2 | no-tests-no-benchmarks: False 3 | unconstrained: False 4 | local-ghc-options: -Werror 5 | -- Work around https://github.com/haskell/haddock/issues/574 6 | haddock: >=8.4 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | dist 2 | dist-* 3 | cabal-dev 4 | *.o 5 | *.hi 6 | *.chi 7 | *.chs.h 8 | *.dyn_o 9 | *.dyn_hi 10 | .hpc 11 | .hsenv 12 | .cabal-sandbox/ 13 | cabal.sandbox.config 14 | *.prof 15 | *.aux 16 | *.hp 17 | *.eventlog 18 | .stack-work/ 19 | cabal.project.local 20 | cabal.project.local~ 21 | .HTF/ 22 | .ghc.environment.* 23 | -------------------------------------------------------------------------------- /tests/Spec/Control/Monad/STSpec.hs: -------------------------------------------------------------------------------- 1 | module Spec.Control.Monad.STSpec (main, spec) where 2 | 3 | import Control.Monad.ST 4 | import Data.Proxy (Proxy(..)) 5 | import Instances.Control.Monad.ST () 6 | import Spec.Utils (matchesTextShowSpec) 7 | import Test.Hspec (Spec, describe, hspec, parallel) 8 | 9 | main :: IO () 10 | main = hspec spec 11 | 12 | spec :: Spec 13 | spec = parallel . describe "ST Int Int" $ 14 | matchesTextShowSpec (Proxy :: Proxy (ST Int Int)) 15 | -------------------------------------------------------------------------------- /src/TextShow/Data/Bool.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE TemplateHaskell #-} 2 | {-# OPTIONS_GHC -Wno-orphans #-} 3 | {-| 4 | Module: TextShow.Data.Bool 5 | Copyright: (C) 2014-2017 Ryan Scott 6 | License: BSD-style (see the file LICENSE) 7 | Maintainer: Ryan Scott 8 | Stability: Provisional 9 | Portability: GHC 10 | 11 | 'TextShow' instance for 'Bool'. 12 | 13 | /Since: 2/ 14 | -} 15 | module TextShow.Data.Bool () where 16 | 17 | import TextShow.TH.Internal (deriveTextShow) 18 | 19 | -- | /Since: 2/ 20 | $(deriveTextShow ''Bool) 21 | -------------------------------------------------------------------------------- /src/TextShow/Data/Void.hs: -------------------------------------------------------------------------------- 1 | {-# OPTIONS_GHC -Wno-orphans #-} 2 | {-| 3 | Module: TextShow.Data.Void 4 | Copyright: (C) 2014-2017 Ryan Scott 5 | License: BSD-style (see the file LICENSE) 6 | Maintainer: Ryan Scott 7 | Stability: Provisional 8 | Portability: GHC 9 | 10 | 'TextShow' instance for 'Void'. 11 | 12 | /Since: 2/ 13 | -} 14 | module TextShow.Data.Void () where 15 | 16 | import Data.Void (Void, absurd) 17 | import Prelude () 18 | import TextShow.Classes (TextShow(..)) 19 | 20 | -- | /Since: 2/ 21 | instance TextShow Void where 22 | showb = absurd 23 | -------------------------------------------------------------------------------- /tests/Instances/Data/Char.hs: -------------------------------------------------------------------------------- 1 | {-# OPTIONS_GHC -Wno-orphans #-} 2 | 3 | {-| 4 | Module: Instances.Data.Char 5 | Copyright: (C) 2014-2017 Ryan Scott 6 | License: BSD-style (see the file LICENSE) 7 | Maintainer: Ryan Scott 8 | Stability: Provisional 9 | Portability: GHC 10 | 11 | 'Arbitrary' instance for 'GeneralCategory'. 12 | -} 13 | module Instances.Data.Char () where 14 | 15 | import Data.Char (GeneralCategory) 16 | import Test.QuickCheck (Arbitrary(..), arbitraryBoundedEnum) 17 | 18 | instance Arbitrary GeneralCategory where 19 | arbitrary = arbitraryBoundedEnum 20 | -------------------------------------------------------------------------------- /src/TextShow/Data/Maybe.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE TemplateHaskell #-} 2 | {-# OPTIONS_GHC -Wno-orphans #-} 3 | {-| 4 | Module: TextShow.Data.Maybe 5 | Copyright: (C) 2014-2017 Ryan Scott 6 | License: BSD-style (see the file LICENSE) 7 | Maintainer: Ryan Scott 8 | Stability: Provisional 9 | Portability: GHC 10 | 11 | 'TextShow' instance for 'Maybe'. 12 | 13 | /Since: 2/ 14 | -} 15 | module TextShow.Data.Maybe () where 16 | 17 | import TextShow.TH.Internal (deriveTextShow, deriveTextShow1) 18 | 19 | -- | /Since: 2/ 20 | $(deriveTextShow ''Maybe) 21 | -- | /Since: 2/ 22 | $(deriveTextShow1 ''Maybe) 23 | -------------------------------------------------------------------------------- /tests/Instances/Data/Ord.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE GeneralizedNewtypeDeriving #-} 2 | {-# LANGUAGE StandaloneDeriving #-} 3 | {-# OPTIONS_GHC -Wno-orphans #-} 4 | 5 | {-| 6 | Module: Instances.Data.Ord 7 | Copyright: (C) 2014-2017 Ryan Scott 8 | License: BSD-style (see the file LICENSE) 9 | Maintainer: Ryan Scott 10 | Stability: Provisional 11 | Portability: GHC 12 | 13 | 'Arbitrary' instance for 'Down'. 14 | -} 15 | module Instances.Data.Ord () where 16 | 17 | import GHC.Exts (Down(..)) 18 | import Test.QuickCheck (Arbitrary) 19 | 20 | deriving instance Arbitrary a => Arbitrary (Down a) 21 | -------------------------------------------------------------------------------- /src/TextShow/System/Exit.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE TemplateHaskell #-} 2 | {-# OPTIONS_GHC -Wno-orphans #-} 3 | {-| 4 | Module: TextShow.System.Exit 5 | Copyright: (C) 2014-2017 Ryan Scott 6 | License: BSD-style (see the file LICENSE) 7 | Maintainer: Ryan Scott 8 | Stability: Provisional 9 | Portability: GHC 10 | 11 | 'TextShow' instance for 'ExitCode'. 12 | 13 | /Since: 2/ 14 | -} 15 | module TextShow.System.Exit () where 16 | 17 | import System.Exit (ExitCode) 18 | 19 | import TextShow.Data.Integral () 20 | import TextShow.TH.Internal (deriveTextShow) 21 | 22 | -- | /Since: 2/ 23 | $(deriveTextShow ''ExitCode) 24 | -------------------------------------------------------------------------------- /tests/Instances/Control/Monad/ST.hs: -------------------------------------------------------------------------------- 1 | {-# OPTIONS_GHC -Wno-orphans #-} 2 | 3 | {-| 4 | Module: Instances.Control.Monad.ST 5 | Copyright: (C) 2014-2017 Ryan Scott 6 | License: BSD-style (see the file LICENSE) 7 | Maintainer: Ryan Scott 8 | Stability: Provisional 9 | Portability: GHC 10 | 11 | 'Arbitrary' instance for 'ST'. 12 | -} 13 | module Instances.Control.Monad.ST () where 14 | 15 | import Control.Monad.ST (ST, fixST) 16 | 17 | import Prelude () 18 | import Prelude.Compat 19 | 20 | import Test.QuickCheck (Arbitrary(..)) 21 | 22 | instance Arbitrary (ST s a) where 23 | arbitrary = pure $ fixST undefined 24 | -------------------------------------------------------------------------------- /tests/Instances/Data/Dynamic.hs: -------------------------------------------------------------------------------- 1 | {-# OPTIONS_GHC -Wno-orphans #-} 2 | 3 | {-| 4 | Module: Instances.Data.Dynamic 5 | Copyright: (C) 2014-2017 Ryan Scott 6 | License: BSD-style (see the file LICENSE) 7 | Maintainer: Ryan Scott 8 | Stability: Provisional 9 | Portability: GHC 10 | 11 | 'Arbitrary' instance for 'Dynamic'. 12 | -} 13 | module Instances.Data.Dynamic () where 14 | 15 | import Data.Dynamic (Dynamic, toDyn) 16 | 17 | import Prelude () 18 | import Prelude.Compat 19 | 20 | import Test.QuickCheck (Arbitrary(..), Gen) 21 | 22 | instance Arbitrary Dynamic where 23 | arbitrary = toDyn <$> (arbitrary :: Gen Int) 24 | -------------------------------------------------------------------------------- /tests/Instances/Data/Semigroup.hs: -------------------------------------------------------------------------------- 1 | {-# OPTIONS_GHC -Wno-orphans #-} 2 | 3 | {-| 4 | Module: Instances.Data.Semigroup 5 | Copyright: (C) 2014-2017 Ryan Scott 6 | License: BSD-style (see the file LICENSE) 7 | Maintainer: Ryan Scott 8 | Stability: Provisional 9 | Portability: GHC 10 | 11 | 'Arbitrary' instance for the 'Arg' datatype. 12 | -} 13 | module Instances.Data.Semigroup () where 14 | 15 | import Data.Semigroup (Arg(..)) 16 | import Instances.Utils.GenericArbitrary (genericArbitrary) 17 | import Test.QuickCheck (Arbitrary(..)) 18 | 19 | instance (Arbitrary a, Arbitrary b) => Arbitrary (Arg a b) where 20 | arbitrary = genericArbitrary 21 | -------------------------------------------------------------------------------- /src/TextShow/Data/Either.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE TemplateHaskell #-} 2 | {-# OPTIONS_GHC -Wno-orphans #-} 3 | {-| 4 | Module: TextShow.Data.Either 5 | Copyright: (C) 2014-2017 Ryan Scott 6 | License: BSD-style (see the file LICENSE) 7 | Maintainer: Ryan Scott 8 | Stability: Provisional 9 | Portability: GHC 10 | 11 | 'TextShow' instance for 'Either'. 12 | 13 | /Since: 2/ 14 | -} 15 | module TextShow.Data.Either () where 16 | 17 | import TextShow.TH.Internal (deriveTextShow, deriveTextShow1, deriveTextShow2) 18 | 19 | -- | /Since: 2/ 20 | $(deriveTextShow ''Either) 21 | -- | /Since: 2/ 22 | $(deriveTextShow1 ''Either) 23 | -- | /Since: 2/ 24 | $(deriveTextShow2 ''Either) 25 | -------------------------------------------------------------------------------- /tests/Spec/Data/RatioSpec.hs: -------------------------------------------------------------------------------- 1 | {-| 2 | Module: Spec.Data.RatioSpec 3 | Copyright: (C) 2014-2017 Ryan Scott 4 | License: BSD-style (see the file LICENSE) 5 | Maintainer: Ryan Scott 6 | Stability: Provisional 7 | Portability: GHC 8 | 9 | @hspec@ test for 'Ratio'. 10 | -} 11 | module Spec.Data.RatioSpec (main, spec) where 12 | 13 | import Data.Proxy (Proxy(..)) 14 | import Data.Ratio (Ratio) 15 | 16 | import Spec.Utils (matchesTextShowSpec) 17 | 18 | import Test.Hspec (Spec, describe, hspec, parallel) 19 | 20 | main :: IO () 21 | main = hspec spec 22 | 23 | spec :: Spec 24 | spec = parallel . describe "Ratio Int" $ do 25 | matchesTextShowSpec (Proxy :: Proxy (Ratio Int)) 26 | -------------------------------------------------------------------------------- /tests/Spec/Data/ComplexSpec.hs: -------------------------------------------------------------------------------- 1 | {-| 2 | Module: Spec.Data.ComplexSpec 3 | Copyright: (C) 2014-2017 Ryan Scott 4 | License: BSD-style (see the file LICENSE) 5 | Maintainer: Ryan Scott 6 | Stability: Provisional 7 | Portability: GHC 8 | 9 | @hspec@ test for 'Complex'. 10 | -} 11 | module Spec.Data.ComplexSpec (main, spec) where 12 | 13 | import Data.Complex (Complex) 14 | import Data.Proxy (Proxy(..)) 15 | 16 | import Spec.Utils (matchesTextShowSpec) 17 | 18 | import Test.Hspec (Spec, describe, hspec, parallel) 19 | 20 | main :: IO () 21 | main = hspec spec 22 | 23 | spec :: Spec 24 | spec = parallel . describe "Complex Double" $ 25 | matchesTextShowSpec (Proxy :: Proxy (Complex Double)) 26 | -------------------------------------------------------------------------------- /tests/Spec/System/ExitSpec.hs: -------------------------------------------------------------------------------- 1 | {-| 2 | Module: Spec.System.ExitSpec 3 | Copyright: (C) 2014-2017 Ryan Scott 4 | License: BSD-style (see the file LICENSE) 5 | Maintainer: Ryan Scott 6 | Stability: Provisional 7 | Portability: GHC 8 | 9 | @hspec@ test for 'ExitCode'. 10 | -} 11 | module Spec.System.ExitSpec (main, spec) where 12 | 13 | import Data.Proxy (Proxy(..)) 14 | import Spec.Utils (matchesTextShowSpec) 15 | import System.Exit (ExitCode) 16 | import Test.Hspec (Spec, describe, hspec, parallel) 17 | import Test.QuickCheck () 18 | 19 | main :: IO () 20 | main = hspec spec 21 | 22 | spec :: Spec 23 | spec = parallel . describe "ExitCode" $ 24 | matchesTextShowSpec (Proxy :: Proxy ExitCode) 25 | -------------------------------------------------------------------------------- /tests/Instances/Data/Monoid.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE CPP #-} 2 | #if MIN_VERSION_base(4,12,0) 3 | {-# LANGUAGE GeneralizedNewtypeDeriving #-} 4 | {-# LANGUAGE StandaloneDeriving #-} 5 | {-# OPTIONS_GHC -Wno-orphans #-} 6 | #endif 7 | {-| 8 | Module: Instances.Data.Monoid 9 | Copyright: (C) 2014-2017 Ryan Scott 10 | License: BSD-style (see the file LICENSE) 11 | Maintainer: Ryan Scott 12 | Stability: Provisional 13 | Portability: GHC 14 | 15 | 'Arbitrary' instance for 'Ap'. 16 | -} 17 | module Instances.Data.Monoid () where 18 | 19 | #if MIN_VERSION_base(4,12,0) 20 | import Data.Monoid (Ap(..)) 21 | import Test.QuickCheck (Arbitrary) 22 | 23 | deriving instance Arbitrary (f a) => Arbitrary (Ap f a) 24 | #endif 25 | -------------------------------------------------------------------------------- /tests/Instances/Data/Type/Coercion.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE CPP #-} 2 | {-# LANGUAGE PolyKinds #-} 3 | {-# OPTIONS_GHC -Wno-orphans #-} 4 | 5 | {-| 6 | Module: Instances.Data.Type.Coercion 7 | Copyright: (C) 2014-2017 Ryan Scott 8 | License: BSD-style (see the file LICENSE) 9 | Maintainer: Ryan Scott 10 | Stability: Provisional 11 | Portability: GHC 12 | 13 | 'Arbitrary' instance for 'Coercion'. 14 | -} 15 | module Instances.Data.Type.Coercion () where 16 | 17 | import Data.Coerce (Coercible) 18 | import Data.Type.Coercion (Coercion(..)) 19 | 20 | import Test.QuickCheck (Arbitrary(..), arbitraryBoundedEnum) 21 | 22 | instance Coercible a b => Arbitrary (Coercion a b) where 23 | arbitrary = arbitraryBoundedEnum 24 | -------------------------------------------------------------------------------- /src/TextShow/Data/List/NonEmpty.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE TemplateHaskell #-} 2 | {-# OPTIONS_GHC -Wno-orphans #-} 3 | 4 | {-| 5 | Module: TextShow.Data.List.NonEmpty 6 | Copyright: (C) 2014-2017 Ryan Scott 7 | License: BSD-style (see the file LICENSE) 8 | Maintainer: Ryan Scott 9 | Stability: Provisional 10 | Portability: GHC 11 | 12 | 'TextShow' instance for 'NonEmpty' lists. 13 | 14 | /Since: 3/ 15 | -} 16 | module TextShow.Data.List.NonEmpty () where 17 | 18 | import Data.List.NonEmpty (NonEmpty) 19 | 20 | import TextShow.Data.List () 21 | import TextShow.TH.Internal (deriveTextShow, deriveTextShow1) 22 | 23 | -- | /Since: 3/ 24 | $(deriveTextShow ''NonEmpty) 25 | -- | /Since: 3/ 26 | $(deriveTextShow1 ''NonEmpty) 27 | -------------------------------------------------------------------------------- /tests/Spec/Numeric/NaturalSpec.hs: -------------------------------------------------------------------------------- 1 | {-| 2 | Module: Spec.Numeric.NaturalSpec 3 | Copyright: (C) 2014-2017 Ryan Scott 4 | License: BSD-style (see the file LICENSE) 5 | Maintainer: Ryan Scott 6 | Stability: Provisional 7 | Portability: GHC 8 | 9 | @hspec@ tests for 'Natural'. 10 | -} 11 | module Spec.Numeric.NaturalSpec (main, spec) where 12 | 13 | import Data.Proxy (Proxy(..)) 14 | import Numeric.Natural (Natural) 15 | import Spec.Utils (matchesTextShowSpec) 16 | import Test.Hspec (Spec, describe, hspec, parallel) 17 | import Test.QuickCheck.Instances () 18 | 19 | main :: IO () 20 | main = hspec spec 21 | 22 | spec :: Spec 23 | spec = parallel . describe "Natural" $ 24 | matchesTextShowSpec (Proxy :: Proxy Natural) 25 | -------------------------------------------------------------------------------- /tests/Instances/Foreign/C/Types.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE CPP #-} 2 | {-# LANGUAGE GeneralizedNewtypeDeriving #-} 3 | {-# LANGUAGE StandaloneDeriving #-} 4 | {-# OPTIONS_GHC -Wno-orphans #-} 5 | 6 | {-| 7 | Module: Instances.Foreign.C.Types 8 | Copyright: (C) 2014-2017 Ryan Scott 9 | License: BSD-style (see the file LICENSE) 10 | Maintainer: Ryan Scott 11 | Stability: Provisional 12 | Portability: GHC 13 | 14 | 'Arbitrary' instances for data types in the "Foreign.C.Types" module. 15 | -} 16 | module Instances.Foreign.C.Types () where 17 | 18 | #if MIN_VERSION_base(4,10,0) 19 | import Foreign.C.Types 20 | import Test.QuickCheck (Arbitrary(..)) 21 | 22 | deriving instance Arbitrary CBool 23 | #endif 24 | -------------------------------------------------------------------------------- /tests/Spec/Data/DynamicSpec.hs: -------------------------------------------------------------------------------- 1 | {-| 2 | Module: Spec.Data.DynamicSpec 3 | Copyright: (C) 2014-2017 Ryan Scott 4 | License: BSD-style (see the file LICENSE) 5 | Maintainer: Ryan Scott 6 | Stability: Provisional 7 | Portability: GHC 8 | 9 | @hspec@ test for 'Dynamic'. 10 | -} 11 | module Spec.Data.DynamicSpec (main, spec) where 12 | 13 | import Data.Dynamic (Dynamic) 14 | import Data.Proxy (Proxy(..)) 15 | 16 | import Instances.Data.Dynamic () 17 | 18 | import Spec.Utils (matchesTextShowSpec) 19 | 20 | import Test.Hspec (Spec, describe, hspec, parallel) 21 | 22 | main :: IO () 23 | main = hspec spec 24 | 25 | spec :: Spec 26 | spec = parallel . describe "Dynamic" $ 27 | matchesTextShowSpec (Proxy :: Proxy Dynamic) 28 | -------------------------------------------------------------------------------- /tests/Instances/Options.hs: -------------------------------------------------------------------------------- 1 | {-# OPTIONS_GHC -Wno-orphans #-} 2 | 3 | {-| 4 | Module: Instances.Options 5 | Copyright: (C) 2014-2017 Ryan Scott 6 | License: BSD-style (see the file LICENSE) 7 | Maintainer: Ryan Scott 8 | Stability: Provisional 9 | Portability: GHC 10 | 11 | 'Arbitrary' instance for 'Options' and related datatypes. 12 | -} 13 | module Instances.Options () where 14 | 15 | import Instances.Utils.GenericArbitrary (genericArbitrary) 16 | import Test.QuickCheck (Arbitrary(..), arbitraryBoundedEnum) 17 | import TextShow.TH (Options(..), GenTextMethods) 18 | 19 | instance Arbitrary Options where 20 | arbitrary = genericArbitrary 21 | 22 | instance Arbitrary GenTextMethods where 23 | arbitrary = arbitraryBoundedEnum 24 | -------------------------------------------------------------------------------- /tests/Spec/Data/BoolSpec.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE CPP #-} 2 | 3 | {-| 4 | Module: Spec.Data.BoolSpec 5 | Copyright: (C) 2014-2017 Ryan Scott 6 | License: BSD-style (see the file LICENSE) 7 | Maintainer: Ryan Scott 8 | Stability: Provisional 9 | Portability: GHC 10 | 11 | @hspec@ tests for 'Bool'. 12 | -} 13 | module Spec.Data.BoolSpec (main, spec) where 14 | 15 | import Data.Proxy (Proxy(..)) 16 | import Spec.Utils (matchesTextShowSpec, genericTextShowSpec) 17 | import Test.Hspec (Spec, describe, hspec, parallel) 18 | 19 | main :: IO () 20 | main = hspec spec 21 | 22 | spec :: Spec 23 | spec = parallel . describe "Bool" $ do 24 | let p :: Proxy Bool 25 | p = Proxy 26 | matchesTextShowSpec p 27 | genericTextShowSpec p 28 | -------------------------------------------------------------------------------- /tests/Spec/FunctionsSpec.hs: -------------------------------------------------------------------------------- 1 | {-| 2 | Module: Spec.FunctionsSpec 3 | Copyright: (C) 2014-2017 Ryan Scott 4 | License: BSD-style (see the file LICENSE) 5 | Maintainer: Ryan Scott 6 | Stability: Provisional 7 | Portability: GHC 8 | 9 | @hspec@ test for the orphan 'TextShow' instance for functions. 10 | -} 11 | module Spec.FunctionsSpec (main, spec) where 12 | 13 | import Data.Proxy (Proxy(..)) 14 | import Spec.Utils (matchesTextShowSpec) 15 | import Test.Hspec (Spec, describe, hspec, parallel) 16 | import Text.Show.Functions () 17 | import TextShow.Functions () 18 | 19 | main :: IO () 20 | main = hspec spec 21 | 22 | spec :: Spec 23 | spec = parallel . describe "Int -> Int" $ 24 | matchesTextShowSpec (Proxy :: Proxy (Int -> Int)) 25 | -------------------------------------------------------------------------------- /src/TextShow/GHC/StaticPtr.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE TemplateHaskell #-} 2 | {-# OPTIONS_GHC -Wno-orphans #-} 3 | {-| 4 | Module: TextShow.GHC.StaticPtr 5 | Copyright: (C) 2014-2017 Ryan Scott 6 | License: BSD-style (see the file LICENSE) 7 | Maintainer: Ryan Scott 8 | Stability: Provisional 9 | Portability: GHC 10 | 11 | 'TextShow' instance for 'StaticPtrInfo'. 12 | 13 | /Since: 2/ 14 | -} 15 | module TextShow.GHC.StaticPtr () where 16 | 17 | import GHC.StaticPtr (StaticPtrInfo) 18 | 19 | import TextShow.Data.Char () 20 | import TextShow.Data.Integral () 21 | import TextShow.Data.List () 22 | import TextShow.Data.Tuple () 23 | import TextShow.TH.Internal (deriveTextShow) 24 | 25 | -- | /Since: 2/ 26 | $(deriveTextShow ''StaticPtrInfo) 27 | -------------------------------------------------------------------------------- /tests/Instances/Data/Floating.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE CPP #-} 2 | {-# LANGUAGE StandaloneDeriving #-} 3 | {-# OPTIONS_GHC -Wno-orphans #-} 4 | 5 | {-| 6 | Module: Instances.Data.Floating 7 | Copyright: (C) 2014-2017 Ryan Scott 8 | License: BSD-style (see the file LICENSE) 9 | Maintainer: Ryan Scott 10 | Stability: Provisional 11 | Portability: GHC 12 | 13 | 'Arbitrary' instance for 'FPFormat'. 14 | -} 15 | module Instances.Data.Floating () where 16 | 17 | import Data.Text.Lazy.Builder.RealFloat (FPFormat(..)) 18 | import Test.QuickCheck (Arbitrary(..), arbitraryBoundedEnum) 19 | 20 | #if !(MIN_VERSION_text(2,0,0)) 21 | deriving instance Bounded FPFormat 22 | #endif 23 | instance Arbitrary FPFormat where 24 | arbitrary = arbitraryBoundedEnum 25 | -------------------------------------------------------------------------------- /tests/Instances/Utils.hs: -------------------------------------------------------------------------------- 1 | {-| 2 | Module: Instances.Utils 3 | Copyright: (C) 2014-2017 Ryan Scott 4 | License: BSD-style (see the file LICENSE) 5 | Maintainer: Ryan Scott 6 | Stability: Provisional 7 | Portability: GHC 8 | 9 | A collection of utilities. 10 | -} 11 | module Instances.Utils (GenericExample(..), (<@>)) where 12 | 13 | -- | A simple data type for testing if 'FromGeneric' and 14 | -- 'FromGeneric1' work as intended. 15 | data GenericExample a = GE1 a (Maybe a) (Maybe (Maybe a)) 16 | | GE2 17 | | GE3 { ge3 :: a } 18 | | a :!@#$: a 19 | 20 | infixl 4 <@> 21 | -- | A useful way to escape a 'Functor' context. 22 | (<@>) :: Functor f => f (a -> b) -> a -> f b 23 | f <@> x = fmap ($ x) f 24 | -------------------------------------------------------------------------------- /src/TextShow/Data/Dynamic.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE OverloadedStrings #-} 2 | {-# OPTIONS_GHC -Wno-orphans #-} 3 | {-| 4 | Module: TextShow.Data.Dynamic 5 | Copyright: (C) 2014-2017 Ryan Scott 6 | License: BSD-style (see the file LICENSE) 7 | Maintainer: Ryan Scott 8 | Stability: Provisional 9 | Portability: GHC 10 | 11 | 'TextShow' instance for 'Dynamic'. 12 | 13 | /Since: 2/ 14 | -} 15 | module TextShow.Data.Dynamic () where 16 | 17 | import Data.Dynamic (Dynamic, dynTypeRep) 18 | 19 | import Prelude () 20 | import Prelude.Compat 21 | 22 | import TextShow.Classes (TextShow(..)) 23 | import TextShow.Data.Typeable () 24 | 25 | -- | /Since: 2/ 26 | instance TextShow Dynamic where 27 | showb dyn = "<<" <> showb (dynTypeRep dyn) <> ">>" 28 | {-# INLINE showb #-} 29 | -------------------------------------------------------------------------------- /tests/Spec/Data/ProxySpec.hs: -------------------------------------------------------------------------------- 1 | {-| 2 | Module: Spec.Data.ProxySpec 3 | Copyright: (C) 2014-2017 Ryan Scott 4 | License: BSD-style (see the file LICENSE) 5 | Maintainer: Ryan Scott 6 | Stability: Provisional 7 | Portability: GHC 8 | 9 | @hspec@ tests for 'Proxy'. 10 | -} 11 | module Spec.Data.ProxySpec (main, spec) where 12 | 13 | import Data.Proxy (Proxy(..)) 14 | 15 | import Spec.Utils (matchesTextShowSpec, genericTextShowSpec) 16 | 17 | import Test.Hspec (Spec, describe, hspec, parallel) 18 | import Test.QuickCheck.Instances () 19 | 20 | main :: IO () 21 | main = hspec spec 22 | 23 | spec :: Spec 24 | spec = parallel . describe "Proxy Int" $ do 25 | let p :: Proxy (Proxy Int) 26 | p = Proxy 27 | matchesTextShowSpec p 28 | genericTextShowSpec p 29 | -------------------------------------------------------------------------------- /tests/Spec/Data/List/NonEmptySpec.hs: -------------------------------------------------------------------------------- 1 | {-| 2 | Module: Spec.Data.List.NonEmptySpec 3 | Copyright: (C) 2014-2017 Ryan Scott 4 | License: BSD-style (see the file LICENSE) 5 | Maintainer: Ryan Scott 6 | Stability: Provisional 7 | Portability: GHC 8 | 9 | @hspec@ test for 'NonEmpty'. 10 | -} 11 | module Spec.Data.List.NonEmptySpec (main, spec) where 12 | 13 | import Data.Proxy (Proxy(..)) 14 | import Data.List.NonEmpty (NonEmpty) 15 | import Data.Orphans () 16 | import Spec.Utils (matchesTextShow1Spec) 17 | import Test.Hspec (Spec, describe, hspec, parallel) 18 | import Test.QuickCheck.Instances () 19 | 20 | main :: IO () 21 | main = hspec spec 22 | 23 | spec :: Spec 24 | spec = parallel . describe "NonEmpty Int" $ 25 | matchesTextShow1Spec (Proxy :: Proxy (NonEmpty Int)) 26 | -------------------------------------------------------------------------------- /tests/Spec/Data/Functor/IdentitySpec.hs: -------------------------------------------------------------------------------- 1 | {-| 2 | Module: Spec.Data.Functor.IdentitySpec 3 | Copyright: (C) 2014-2017 Ryan Scott 4 | License: BSD-style (see the file LICENSE) 5 | Maintainer: Ryan Scott 6 | Stability: Provisional 7 | Portability: GHC 8 | 9 | @hspec@ test for 'Identity'. 10 | -} 11 | module Spec.Data.Functor.IdentitySpec (main, spec) where 12 | 13 | import Control.Monad.Trans.Instances () 14 | 15 | import Data.Functor.Identity (Identity) 16 | import Data.Proxy (Proxy(..)) 17 | 18 | import Spec.Utils (matchesTextShow1Spec) 19 | 20 | import Test.Hspec (Spec, describe, hspec, parallel) 21 | 22 | main :: IO () 23 | main = hspec spec 24 | 25 | spec :: Spec 26 | spec = parallel . describe "Identity Int" $ 27 | matchesTextShow1Spec (Proxy :: Proxy (Identity Int)) 28 | -------------------------------------------------------------------------------- /tests/Spec/Data/EitherSpec.hs: -------------------------------------------------------------------------------- 1 | {-| 2 | Module: Spec.Data.EitherSpec 3 | Copyright: (C) 2014-2017 Ryan Scott 4 | License: BSD-style (see the file LICENSE) 5 | Maintainer: Ryan Scott 6 | Stability: Provisional 7 | Portability: GHC 8 | 9 | @hspec@ tests for 'Either'. 10 | -} 11 | module Spec.Data.EitherSpec (main, spec) where 12 | 13 | import Data.Proxy (Proxy(..)) 14 | import Spec.Utils (matchesTextShow1Spec, genericTextShowSpec, genericTextShow1Spec) 15 | import Test.Hspec (Spec, describe, hspec, parallel) 16 | 17 | main :: IO () 18 | main = hspec spec 19 | 20 | spec :: Spec 21 | spec = parallel . describe "Either Int Int" $ do 22 | let p :: Proxy (Either Int Int) 23 | p = Proxy 24 | matchesTextShow1Spec p 25 | genericTextShowSpec p 26 | genericTextShow1Spec p 27 | -------------------------------------------------------------------------------- /tests/Instances/GHC/StaticPtr.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE DeriveGeneric #-} 2 | {-# LANGUAGE StandaloneDeriving #-} 3 | {-# OPTIONS_GHC -Wno-orphans #-} 4 | 5 | {-| 6 | Module: Instances.GHC.StaticPtr 7 | Copyright: (C) 2014-2017 Ryan Scott 8 | License: BSD-style (see the file LICENSE) 9 | Maintainer: Ryan Scott 10 | Stability: Provisional 11 | Portability: GHC 12 | 13 | 'Arbitrary' instance for 'StaticPtrInfo'. 14 | -} 15 | module Instances.GHC.StaticPtr () where 16 | 17 | import GHC.Generics (Generic) 18 | import GHC.StaticPtr (StaticPtrInfo(..)) 19 | 20 | import Instances.Utils.GenericArbitrary (genericArbitrary) 21 | 22 | import Test.QuickCheck (Arbitrary(..)) 23 | 24 | deriving instance Generic StaticPtrInfo 25 | instance Arbitrary StaticPtrInfo where 26 | arbitrary = genericArbitrary 27 | -------------------------------------------------------------------------------- /tests/Instances/Data/Type/Equality.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE PolyKinds #-} 2 | {-# LANGUAGE TypeFamilies #-} 3 | {-# LANGUAGE TypeOperators #-} 4 | {-# OPTIONS_GHC -Wno-orphans #-} 5 | 6 | {-| 7 | Module: Instances.Data.Type.Equality 8 | Copyright: (C) 2014-2017 Ryan Scott 9 | License: BSD-style (see the file LICENSE) 10 | Maintainer: Ryan Scott 11 | Stability: Provisional 12 | Portability: GHC 13 | 14 | 'Arbitrary' instance for '(:~:)'. 15 | -} 16 | module Instances.Data.Type.Equality () where 17 | 18 | import Data.Type.Equality.Compat 19 | 20 | import Test.QuickCheck (Arbitrary(..), arbitraryBoundedEnum) 21 | 22 | instance a ~ b => Arbitrary (a :~: b) where 23 | arbitrary = arbitraryBoundedEnum 24 | 25 | instance a ~~ b => Arbitrary (a :~~: b) where 26 | arbitrary = arbitraryBoundedEnum 27 | -------------------------------------------------------------------------------- /tests/Spec/Data/Functor/SumSpec.hs: -------------------------------------------------------------------------------- 1 | {-| 2 | Module: Spec.Data.Functor.SumSpec 3 | Copyright: (C) 2014-2017 Ryan Scott 4 | License: BSD-style (see the file LICENSE) 5 | Maintainer: Ryan Scott 6 | Stability: Provisional 7 | Portability: GHC 8 | 9 | @hspec@ test for 'Sum'. 10 | -} 11 | module Spec.Data.Functor.SumSpec (main, spec) where 12 | 13 | import Control.Monad.Trans.Instances () 14 | 15 | import Data.Functor.Sum (Sum) 16 | import Data.Proxy (Proxy(..)) 17 | 18 | import Spec.Utils (matchesTextShow1Spec) 19 | 20 | import Test.Hspec (Spec, describe, hspec, parallel) 21 | import Test.QuickCheck.Instances () 22 | 23 | main :: IO () 24 | main = hspec spec 25 | 26 | spec :: Spec 27 | spec = parallel . describe "Sum Maybe Maybe Int" $ 28 | matchesTextShow1Spec (Proxy :: Proxy (Sum Maybe Maybe Int)) 29 | -------------------------------------------------------------------------------- /tests/Instances/GHC/Conc/Windows.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE CPP #-} 2 | {-# LANGUAGE StandaloneDeriving #-} 3 | {-# OPTIONS_GHC -Wno-orphans #-} 4 | 5 | {-| 6 | Module: Instances.GHC.Conc.Windows 7 | Copyright: (C) 2014-2017 Ryan Scott 8 | License: BSD-style (see the file LICENSE) 9 | Maintainer: Ryan Scott 10 | Stability: Provisional 11 | Portability: GHC 12 | 13 | 'Arbitrary' instance for 'ConsoleEvent'. 14 | -} 15 | module Instances.GHC.Conc.Windows () where 16 | 17 | #if !defined(__GHCJS__) && !defined(ghcjs_HOST_OS) && defined(mingw32_HOST_OS) 18 | import GHC.Conc.Windows (ConsoleEvent(..)) 19 | import Test.QuickCheck (Arbitrary(..), arbitraryBoundedEnum) 20 | 21 | deriving instance Bounded ConsoleEvent 22 | instance Arbitrary ConsoleEvent where 23 | arbitrary = arbitraryBoundedEnum 24 | #endif 25 | -------------------------------------------------------------------------------- /tests/Spec/Data/MaybeSpec.hs: -------------------------------------------------------------------------------- 1 | {-| 2 | Module: Spec.Data.MaybeSpec 3 | Copyright: (C) 2014-2017 Ryan Scott 4 | License: BSD-style (see the file LICENSE) 5 | Maintainer: Ryan Scott 6 | Stability: Provisional 7 | Portability: GHC 8 | 9 | @hspec@ tests for 'Maybe'. 10 | -} 11 | module Spec.Data.MaybeSpec (main, spec) where 12 | 13 | import Data.Orphans () 14 | import Data.Proxy (Proxy(..)) 15 | 16 | import Spec.Utils (matchesTextShow1Spec, genericTextShowSpec, genericTextShow1Spec) 17 | 18 | import Test.Hspec (Spec, describe, hspec, parallel) 19 | 20 | main :: IO () 21 | main = hspec spec 22 | 23 | spec :: Spec 24 | spec = parallel . describe "Maybe Int" $ do 25 | let p :: Proxy (Maybe Int) 26 | p = Proxy 27 | matchesTextShow1Spec p 28 | genericTextShowSpec p 29 | genericTextShow1Spec p 30 | -------------------------------------------------------------------------------- /tests/Spec/GHC/StaticPtrSpec.hs: -------------------------------------------------------------------------------- 1 | {-| 2 | Module: Spec.GHC.StaticPtrSpec 3 | Copyright: (C) 2014-2017 Ryan Scott 4 | License: BSD-style (see the file LICENSE) 5 | Maintainer: Ryan Scott 6 | Stability: Provisional 7 | Portability: GHC 8 | 9 | @hspec@ test for 'StaticPtr'. 10 | -} 11 | module Spec.GHC.StaticPtrSpec (main, spec) where 12 | 13 | import Data.Proxy (Proxy(..)) 14 | 15 | import GHC.StaticPtr (StaticPtrInfo) 16 | 17 | import Instances.GHC.StaticPtr () 18 | 19 | import Prelude () 20 | import Prelude.Compat 21 | 22 | import Spec.Utils (matchesTextShowSpec) 23 | 24 | import Test.Hspec (Spec, describe, hspec, parallel) 25 | 26 | main :: IO () 27 | main = hspec spec 28 | 29 | spec :: Spec 30 | spec = parallel $ 31 | describe "StaticPtrInfo" $ 32 | matchesTextShowSpec (Proxy :: Proxy StaticPtrInfo) 33 | -------------------------------------------------------------------------------- /tests/Spec/Data/Functor/ComposeSpec.hs: -------------------------------------------------------------------------------- 1 | {-| 2 | Module: Spec.Data.Functor.ComposeSpec 3 | Copyright: (C) 2014-2017 Ryan Scott 4 | License: BSD-style (see the file LICENSE) 5 | Maintainer: Ryan Scott 6 | Stability: Provisional 7 | Portability: GHC 8 | 9 | @hspec@ test for 'Compose'. 10 | -} 11 | module Spec.Data.Functor.ComposeSpec (main, spec) where 12 | 13 | import Control.Monad.Trans.Instances () 14 | 15 | import Data.Functor.Compose (Compose) 16 | import Data.Proxy (Proxy(..)) 17 | 18 | import Spec.Utils (matchesTextShow1Spec) 19 | 20 | import Test.Hspec (Spec, describe, hspec, parallel) 21 | import Test.QuickCheck.Instances () 22 | 23 | main :: IO () 24 | main = hspec spec 25 | 26 | spec :: Spec 27 | spec = parallel . describe "Compose Maybe Maybe Int" $ 28 | matchesTextShow1Spec (Proxy :: Proxy (Compose Maybe Maybe Int)) 29 | -------------------------------------------------------------------------------- /tests/Spec/Data/Functor/ProductSpec.hs: -------------------------------------------------------------------------------- 1 | {-| 2 | Module: Spec.Data.Functor.ProductSpec 3 | Copyright: (C) 2014-2017 Ryan Scott 4 | License: BSD-style (see the file LICENSE) 5 | Maintainer: Ryan Scott 6 | Stability: Provisional 7 | Portability: GHC 8 | 9 | @hspec@ test for 'Product'. 10 | -} 11 | module Spec.Data.Functor.ProductSpec (main, spec) where 12 | 13 | import Control.Monad.Trans.Instances () 14 | 15 | import Data.Functor.Product (Product) 16 | import Data.Proxy (Proxy(..)) 17 | 18 | import Spec.Utils (matchesTextShow1Spec) 19 | 20 | import Test.Hspec (Spec, describe, hspec, parallel) 21 | import Test.QuickCheck.Instances () 22 | 23 | main :: IO () 24 | main = hspec spec 25 | 26 | spec :: Spec 27 | spec = parallel . describe "Product Maybe Maybe Int" $ 28 | matchesTextShow1Spec (Proxy :: Proxy (Product Maybe Maybe Int)) 29 | -------------------------------------------------------------------------------- /tests/Spec/Derived/RankNTypesSpec.hs: -------------------------------------------------------------------------------- 1 | {-| 2 | Module: Spec.Derived.RankNTypesSpec 3 | Copyright: (C) 2014-2017 Ryan Scott 4 | License: BSD-style (see the file LICENSE) 5 | Maintainer: Ryan Scott 6 | Stability: Provisional 7 | Portability: GHC 8 | 9 | @hspec@ tests for data types with rank-n voodoo. 10 | -} 11 | module Spec.Derived.RankNTypesSpec (main, spec) where 12 | 13 | import Data.Proxy (Proxy(..)) 14 | import Derived.RankNTypes 15 | import Spec.Utils (matchesTextShow1Spec) 16 | import Test.Hspec (Spec, describe, hspec, parallel) 17 | 18 | main :: IO () 19 | main = hspec spec 20 | 21 | spec :: Spec 22 | spec = parallel $ do 23 | describe "TyCon Int Int" $ 24 | matchesTextShow1Spec (Proxy :: Proxy (TyCon Int Int)) 25 | describe "TyFamily Int Int" $ 26 | matchesTextShow1Spec (Proxy :: Proxy (TyFamily Int Int)) 27 | -------------------------------------------------------------------------------- /tests/Spec/Text/ReadSpec.hs: -------------------------------------------------------------------------------- 1 | {-| 2 | Module: Spec.Text.ReadSpec 3 | Copyright: (C) 2014-2017 Ryan Scott 4 | License: BSD-style (see the file LICENSE) 5 | Maintainer: Ryan Scott 6 | Stability: Provisional 7 | Portability: GHC 8 | 9 | @hspec@ tests for data types in the "Text.Read" module. 10 | -} 11 | module Spec.Text.ReadSpec (main, spec) where 12 | 13 | import Data.Proxy (Proxy(..)) 14 | import Instances.Text.Read () 15 | import Spec.Utils (matchesTextShowSpec) 16 | import Test.Hspec (Spec, describe, hspec, parallel) 17 | import Text.Read (Lexeme) 18 | import Text.Read.Lex (Number) 19 | 20 | main :: IO () 21 | main = hspec spec 22 | 23 | spec :: Spec 24 | spec = parallel $ do 25 | describe "Lexeme" $ 26 | matchesTextShowSpec (Proxy :: Proxy Lexeme) 27 | describe "Number" $ 28 | matchesTextShowSpec (Proxy :: Proxy Number) 29 | -------------------------------------------------------------------------------- /tests/Spec/GHC/FingerprintSpec.hs: -------------------------------------------------------------------------------- 1 | {-| 2 | Module: Spec.GHC.FingerprintSpec 3 | Copyright: (C) 2014-2017 Ryan Scott 4 | License: BSD-style (see the file LICENSE) 5 | Maintainer: Ryan Scott 6 | Stability: Provisional 7 | Portability: GHC 8 | 9 | @hspec@ tests for 'Fingerprint'. 10 | -} 11 | module Spec.GHC.FingerprintSpec (main, spec) where 12 | 13 | import Data.Proxy (Proxy(..)) 14 | import Data.Orphans () 15 | 16 | import GHC.Fingerprint.Type (Fingerprint) 17 | 18 | import Instances.GHC.Fingerprint () 19 | 20 | import Prelude () 21 | import Prelude.Compat 22 | 23 | import Spec.Utils (matchesTextShowSpec) 24 | 25 | import Test.Hspec (Spec, describe, hspec, parallel) 26 | 27 | main :: IO () 28 | main = hspec spec 29 | 30 | spec :: Spec 31 | spec = parallel $ 32 | describe "Fingerprint" $ 33 | matchesTextShowSpec (Proxy :: Proxy Fingerprint) 34 | -------------------------------------------------------------------------------- /src/TextShow/Data/Functor/Sum.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE OverloadedStrings #-} 2 | {-# LANGUAGE TemplateHaskell #-} 3 | {-# OPTIONS_GHC -Wno-orphans #-} 4 | 5 | {-| 6 | Module: TextShow.Data.Functor.Sum 7 | Copyright: (C) 2014-2017 Ryan Scott 8 | License: BSD-style (see the file LICENSE) 9 | Maintainer: Ryan Scott 10 | Stability: Provisional 11 | Portability: GHC 12 | 13 | 'TextShow' instance for 'Sum'. 14 | 15 | /Since: 3/ 16 | -} 17 | module TextShow.Data.Functor.Sum () where 18 | 19 | import Data.Functor.Sum (Sum) 20 | 21 | import TextShow.Classes (TextShow(..), TextShow1(..), showbPrec1) 22 | import TextShow.TH.Internal (deriveTextShow1) 23 | 24 | -- | /Since: 3/ 25 | $(deriveTextShow1 ''Sum) 26 | 27 | -- | /Since: 3/ 28 | instance (TextShow1 f, TextShow1 g, TextShow a) => TextShow (Sum f g a) where 29 | showbPrec = showbPrec1 30 | {-# INLINE showbPrec #-} 31 | -------------------------------------------------------------------------------- /src/TextShow/TH.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE TemplateHaskell #-} 2 | {-# OPTIONS_GHC -Wno-orphans #-} 3 | 4 | {-| 5 | Module: TextShow.TH 6 | Copyright: (C) 2014-2017 Ryan Scott 7 | License: BSD-style (see the file LICENSE) 8 | Maintainer: Ryan Scott 9 | Stability: Provisional 10 | Portability: GHC 11 | 12 | Functions to mechanically derive 'TextShow', 'TextShow1', or 'TextShow2' instances, 13 | or to splice @show@-related expressions into Haskell source code. You need to enable 14 | the @TemplateHaskell@ language extension in order to use this module. 15 | 16 | /Since: 2/ 17 | -} 18 | module TextShow.TH (module TextShow.TH.Internal) where 19 | 20 | import TextShow.Instances () 21 | import TextShow.TH.Internal 22 | 23 | ------------------------------------------------------------------------------- 24 | 25 | $(deriveTextShow ''GenTextMethods) 26 | $(deriveTextShow ''Options) 27 | -------------------------------------------------------------------------------- /src/TextShow/Text/Read.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE TemplateHaskell #-} 2 | {-# OPTIONS_GHC -Wno-orphans #-} 3 | {-| 4 | Module: TextShow.Text.Read 5 | Copyright: (C) 2014-2017 Ryan Scott 6 | License: BSD-style (see the file LICENSE) 7 | Maintainer: Ryan Scott 8 | Stability: Provisional 9 | Portability: GHC 10 | 11 | 'TextShow' instance for 'Lexeme' (and 'Number', if using a 12 | recent-enough version of @base@). 13 | 14 | /Since: 2/ 15 | -} 16 | module TextShow.Text.Read () where 17 | 18 | import Text.Read.Lex (Lexeme, Number) 19 | 20 | import TextShow.Data.Char () 21 | import TextShow.Data.Integral () 22 | import TextShow.Data.List () 23 | import TextShow.Data.Maybe () 24 | import TextShow.Data.Ratio () 25 | import TextShow.TH.Internal (deriveTextShow) 26 | 27 | -- | /Since: 2/ 28 | $(deriveTextShow ''Number) 29 | 30 | -- | /Since: 2/ 31 | $(deriveTextShow ''Lexeme) 32 | -------------------------------------------------------------------------------- /src/TextShow/GHC/Conc/Windows.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE CPP #-} 2 | 3 | #if !defined(__GHCJS__) && !defined(ghcjs_HOST_OS) && defined(mingw32_HOST_OS) 4 | {-# LANGUAGE TemplateHaskell #-} 5 | {-# OPTIONS_GHC -Wno-orphans #-} 6 | #endif 7 | {-| 8 | Module: TextShow.GHC.Conc.Windows 9 | Copyright: (C) 2014-2017 Ryan Scott 10 | License: BSD-style (see the file LICENSE) 11 | Maintainer: Ryan Scott 12 | Stability: Provisional 13 | Portability: GHC 14 | 15 | 'TextShow' instance for 'ConsoleEvent'. 16 | Only provided if using Windows, and not using GHCJS. 17 | 18 | /Since: 2/ 19 | -} 20 | module TextShow.GHC.Conc.Windows () where 21 | 22 | #if !defined(__GHCJS__) && !defined(ghcjs_HOST_OS) && defined(mingw32_HOST_OS) 23 | import GHC.Conc.Windows (ConsoleEvent) 24 | import TextShow.TH.Internal (deriveTextShow) 25 | 26 | -- | /Since: 2/ 27 | $(deriveTextShow ''ConsoleEvent) 28 | #endif 29 | -------------------------------------------------------------------------------- /tests/Spec/Derived/DatatypeContextsSpec.hs: -------------------------------------------------------------------------------- 1 | {-| 2 | Module: Spec.Derived.DatatypeContextsSpec 3 | Copyright: (C) 2014-2017 Ryan Scott 4 | License: BSD-style (see the file LICENSE) 5 | Maintainer: Ryan Scott 6 | Stability: Provisional 7 | Portability: GHC 8 | 9 | @hspec@ tests for data types with DatatypeContexts (eww). 10 | -} 11 | module Spec.Derived.DatatypeContextsSpec (main, spec) where 12 | 13 | import Data.Proxy (Proxy(..)) 14 | import Derived.DatatypeContexts 15 | import Spec.Utils (matchesTextShow1Spec) 16 | import Test.Hspec (Spec, describe, hspec, parallel) 17 | 18 | main :: IO () 19 | main = hspec spec 20 | 21 | spec :: Spec 22 | spec = parallel $ do 23 | describe "TyCon Int Int Int" $ 24 | matchesTextShow1Spec (Proxy :: Proxy (TyCon Int Int Int)) 25 | describe "TyFamily Int Int Int" $ 26 | matchesTextShow1Spec (Proxy :: Proxy (TyFamily Int Int Int)) 27 | -------------------------------------------------------------------------------- /tests/Spec/GHC/StackSpec.hs: -------------------------------------------------------------------------------- 1 | {-| 2 | Module: Spec.GHC.StackSpec 3 | Copyright: (C) 2014-2017 Ryan Scott 4 | License: BSD-style (see the file LICENSE) 5 | Maintainer: Ryan Scott 6 | Stability: Provisional 7 | Portability: GHC 8 | 9 | @hspec@ tests for 'CallStack' and 'SrcLoc'. 10 | -} 11 | module Spec.GHC.StackSpec (main, spec) where 12 | 13 | import Data.Proxy (Proxy(..)) 14 | 15 | import GHC.Stack (CallStack, SrcLoc) 16 | 17 | import Instances.GHC.Stack () 18 | 19 | import Prelude () 20 | import Prelude.Compat 21 | 22 | import Spec.Utils (matchesTextShowSpec) 23 | 24 | import Test.Hspec (Spec, describe, hspec, parallel) 25 | 26 | main :: IO () 27 | main = hspec spec 28 | 29 | spec :: Spec 30 | spec = parallel $ do 31 | describe "CallStack" $ 32 | matchesTextShowSpec (Proxy :: Proxy CallStack) 33 | describe "SrcLoc" $ 34 | matchesTextShowSpec (Proxy :: Proxy SrcLoc) 35 | -------------------------------------------------------------------------------- /src/TextShow/Data/Functor/Product.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE OverloadedStrings #-} 2 | {-# LANGUAGE TemplateHaskell #-} 3 | {-# OPTIONS_GHC -Wno-orphans #-} 4 | 5 | {-| 6 | Module: TextShow.Data.Functor.Product 7 | Copyright: (C) 2014-2017 Ryan Scott 8 | License: BSD-style (see the file LICENSE) 9 | Maintainer: Ryan Scott 10 | Stability: Provisional 11 | Portability: GHC 12 | 13 | 'TextShow' instance for 'Product'. 14 | 15 | /Since: 3/ 16 | -} 17 | module TextShow.Data.Functor.Product () where 18 | 19 | import Data.Functor.Product (Product(..)) 20 | 21 | import TextShow.Classes (TextShow(..), TextShow1(..), showbPrec1) 22 | import TextShow.TH.Internal (deriveTextShow1) 23 | 24 | -- | /Since: 3/ 25 | $(deriveTextShow1 ''Product) 26 | 27 | -- | /Since: 3/ 28 | instance (TextShow1 f, TextShow1 g, TextShow a) => TextShow (Product f g a) where 29 | showbPrec = showbPrec1 30 | {-# INLINE showbPrec #-} 31 | -------------------------------------------------------------------------------- /tests/Spec/Data/Type/CoercionSpec.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE CPP #-} 2 | 3 | {-| 4 | Module: Spec.Data.Type.CoercionSpec 5 | Copyright: (C) 2014-2017 Ryan Scott 6 | License: BSD-style (see the file LICENSE) 7 | Maintainer: Ryan Scott 8 | Stability: Provisional 9 | Portability: GHC 10 | 11 | @hspec@ test for 'Coercion'. 12 | -} 13 | module Spec.Data.Type.CoercionSpec (main, spec) where 14 | 15 | import Data.Monoid (All(..)) 16 | import Data.Proxy (Proxy(..)) 17 | import Data.Type.Coercion (Coercion) 18 | 19 | import Instances.Data.Type.Coercion () 20 | 21 | import Prelude () 22 | import Prelude.Compat 23 | 24 | import Spec.Utils (matchesTextShowSpec) 25 | 26 | import Test.Hspec (Spec, describe, hspec, parallel) 27 | 28 | main :: IO () 29 | main = hspec spec 30 | 31 | spec :: Spec 32 | spec = parallel $ 33 | describe "Coercion All Bool" $ 34 | matchesTextShowSpec (Proxy :: Proxy (Coercion All Bool)) 35 | -------------------------------------------------------------------------------- /tests/Spec/Data/VersionSpec.hs: -------------------------------------------------------------------------------- 1 | module Spec.Data.VersionSpec (main, spec) where 2 | 3 | import Data.Proxy (Proxy(..)) 4 | import Data.Version (Version, showVersion) 5 | 6 | import Spec.Utils (matchesTextShowSpec) 7 | 8 | import Test.Hspec (Expectation, Spec, describe, hspec, parallel, shouldBe) 9 | import Test.Hspec.QuickCheck (prop) 10 | 11 | import TextShow (fromString) 12 | import TextShow.Data.Version (showbVersion) 13 | 14 | main :: IO () 15 | main = hspec spec 16 | 17 | spec :: Spec 18 | spec = parallel $ do 19 | describe "Version" $ 20 | matchesTextShowSpec (Proxy :: Proxy Version) 21 | describe "showbVersion" $ 22 | prop "has the same output as showVersion" prop_showVersion 23 | 24 | -- | Verifies 'showVersion' and 'showbVersion' generate the same output. 25 | prop_showVersion :: Version -> Expectation 26 | prop_showVersion v = fromString (showVersion v) `shouldBe` showbVersion v 27 | -------------------------------------------------------------------------------- /tests/Spec/Derived/ExistentialQuantificationSpec.hs: -------------------------------------------------------------------------------- 1 | {-| 2 | Module: Spec.Derived.ExistentialQuantificationSpec 3 | Copyright: (C) 2014-2017 Ryan Scott 4 | License: BSD-style (see the file LICENSE) 5 | Maintainer: Ryan Scott 6 | Stability: Provisional 7 | Portability: GHC 8 | 9 | @hspec@ tests for existentially quantified data types. 10 | -} 11 | module Spec.Derived.ExistentialQuantificationSpec (main, spec) where 12 | 13 | import Data.Proxy (Proxy(..)) 14 | import Derived.ExistentialQuantification 15 | import Spec.Utils (matchesTextShow1Spec) 16 | import Test.Hspec (Spec, describe, hspec, parallel) 17 | 18 | main :: IO () 19 | main = hspec spec 20 | 21 | spec :: Spec 22 | spec = parallel $ do 23 | describe "TyCon Int Int Int Int" $ 24 | matchesTextShow1Spec (Proxy :: Proxy (TyCon Int Int Int Int)) 25 | describe "TyFamily Int Int Int Int" $ 26 | matchesTextShow1Spec (Proxy :: Proxy (TyFamily Int Int Int Int)) 27 | -------------------------------------------------------------------------------- /tests/Instances/GHC/Fingerprint.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE CPP #-} 2 | {-# LANGUAGE DeriveGeneric #-} 3 | {-# LANGUAGE StandaloneDeriving #-} 4 | {-# OPTIONS_GHC -Wno-orphans #-} 5 | 6 | {-| 7 | Module: Instances.GHC.Fingerprint 8 | Copyright: (C) 2014-2017 Ryan Scott 9 | License: BSD-style (see the file LICENSE) 10 | Maintainer: Ryan Scott 11 | Stability: Provisional 12 | Portability: GHC 13 | 14 | 'Arbitrary' instance for 'Fingerprint'. 15 | -} 16 | module Instances.GHC.Fingerprint () where 17 | 18 | import GHC.Fingerprint.Type (Fingerprint(..)) 19 | #if !(MIN_VERSION_base(4,15,0)) 20 | import GHC.Generics (Generic) 21 | #endif 22 | 23 | import Instances.Utils.GenericArbitrary (genericArbitrary) 24 | 25 | import Test.QuickCheck (Arbitrary(..)) 26 | 27 | instance Arbitrary Fingerprint where 28 | arbitrary = genericArbitrary 29 | 30 | #if !(MIN_VERSION_base(4,15,0)) 31 | deriving instance Generic Fingerprint 32 | #endif 33 | -------------------------------------------------------------------------------- /tests/Instances/GHC/Stats.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE CPP #-} 2 | 3 | #if !(MIN_VERSION_base(4,11,0)) 4 | {-# LANGUAGE DeriveGeneric #-} 5 | {-# LANGUAGE StandaloneDeriving #-} 6 | {-# OPTIONS_GHC -Wno-deprecations #-} 7 | {-# OPTIONS_GHC -Wno-orphans #-} 8 | #endif 9 | 10 | {-| 11 | Module: Instances.GHC.Stats 12 | Copyright: (C) 2014-2017 Ryan Scott 13 | License: BSD-style (see the file LICENSE) 14 | Maintainer: Ryan Scott 15 | Stability: Provisional 16 | Portability: GHC 17 | 18 | 'Arbitrary' instance for 'GCStats'. 19 | -} 20 | module Instances.GHC.Stats () where 21 | 22 | #if !(MIN_VERSION_base(4,11,0)) 23 | import GHC.Generics (Generic) 24 | import GHC.Stats (GCStats(..)) 25 | 26 | import Instances.Utils.GenericArbitrary (genericArbitrary) 27 | 28 | import Test.QuickCheck (Arbitrary(..)) 29 | 30 | deriving instance Generic GCStats 31 | instance Arbitrary GCStats where 32 | arbitrary = genericArbitrary 33 | #endif 34 | -------------------------------------------------------------------------------- /src/TextShow/Data/Type/Coercion.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE GADTs #-} 2 | {-# LANGUAGE PolyKinds #-} 3 | {-# LANGUAGE TemplateHaskell #-} 4 | {-# OPTIONS_GHC -Wno-orphans #-} 5 | {-| 6 | Module: TextShow.Data.Type.Coercion 7 | Copyright: (C) 2014-2017 Ryan Scott 8 | License: BSD-style (see the file LICENSE) 9 | Maintainer: Ryan Scott 10 | Stability: Provisional 11 | Portability: GHC 12 | 13 | 'TextShow' instance for representational equality. 14 | 15 | /Since: 2/ 16 | -} 17 | module TextShow.Data.Type.Coercion () where 18 | 19 | import Data.Type.Coercion (Coercion) 20 | 21 | import TextShow.Classes (TextShow1(..)) 22 | import TextShow.TH.Internal (deriveTextShow, deriveTextShow2, makeLiftShowbPrec) 23 | 24 | -- | /Since: 2/ 25 | $(deriveTextShow ''Coercion) 26 | 27 | -- | /Since: 2/ 28 | instance TextShow1 (Coercion a) where 29 | liftShowbPrec = $(makeLiftShowbPrec ''Coercion) 30 | 31 | -- | /Since: 2/ 32 | $(deriveTextShow2 ''Coercion) 33 | -------------------------------------------------------------------------------- /tests/Spec/Derived/TypeFamiliesSpec.hs: -------------------------------------------------------------------------------- 1 | {-| 2 | Module: Spec.Derived.TypeFamiliesSpec 3 | Copyright: (C) 2020 Ryan Scott 4 | License: BSD-style (see the file LICENSE) 5 | Maintainer: Ryan Scott 6 | Stability: Provisional 7 | Portability: GHC 8 | 9 | @hspec@ tests involving corner case-provoking type families. 10 | -} 11 | module Spec.Derived.TypeFamiliesSpec (main, spec) where 12 | 13 | import Data.Proxy (Proxy(..)) 14 | 15 | import Derived.TypeFamilies 16 | 17 | import Prelude () 18 | import Prelude.Compat 19 | 20 | import Spec.Utils (matchesTextShow1Spec) 21 | 22 | import Test.Hspec (Spec, describe, hspec, parallel) 23 | 24 | main :: IO () 25 | main = hspec spec 26 | 27 | spec :: Spec 28 | spec = parallel $ do 29 | describe "TyConOverSat Int Int" $ 30 | matchesTextShow1Spec (Proxy :: Proxy (TyConOverSat Int Int)) 31 | describe "TyFamilyOverSat Int Int" $ 32 | matchesTextShow1Spec (Proxy :: Proxy (TyFamilyOverSat Int Int)) 33 | -------------------------------------------------------------------------------- /tests/Spec/Data/OrdSpec.hs: -------------------------------------------------------------------------------- 1 | {-| 2 | Module: Spec.Data.OrdSpec 3 | Copyright: (C) 2014-2017 Ryan Scott 4 | License: BSD-style (see the file LICENSE) 5 | Maintainer: Ryan Scott 6 | Stability: Provisional 7 | Portability: GHC 8 | 9 | @hspec@ tests for data types in the "Data.Ord" module. 10 | -} 11 | module Spec.Data.OrdSpec (main, spec) where 12 | 13 | import Data.Orphans () 14 | import Data.Proxy (Proxy(..)) 15 | 16 | import GHC.Exts (Down) 17 | 18 | import Instances.Data.Ord () 19 | 20 | import Spec.Utils (matchesTextShowSpec, genericTextShowSpec) 21 | 22 | import Test.Hspec (Spec, describe, hspec, parallel) 23 | 24 | main :: IO () 25 | main = hspec spec 26 | 27 | spec :: Spec 28 | spec = parallel $ do 29 | describe "Ordering" $ do 30 | let p :: Proxy Ordering 31 | p = Proxy 32 | matchesTextShowSpec p 33 | genericTextShowSpec p 34 | describe "Down Int" $ 35 | matchesTextShowSpec (Proxy :: Proxy (Down Int)) 36 | -------------------------------------------------------------------------------- /src/TextShow/GHC/Stack.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE CPP #-} 2 | {-# LANGUAGE TemplateHaskell #-} 3 | {-# OPTIONS_GHC -Wno-orphans #-} 4 | {-| 5 | Module: TextShow.GHC.Stack 6 | Copyright: (C) 2014-2017 Ryan Scott 7 | License: BSD-style (see the file LICENSE) 8 | Maintainer: Ryan Scott 9 | Stability: Provisional 10 | Portability: GHC 11 | 12 | 'TextShow' instances for 'CallStack' and 'SrcLoc' values. 13 | 14 | /Since: 3.0.1/ 15 | -} 16 | module TextShow.GHC.Stack () where 17 | 18 | import GHC.Stack (CallStack, SrcLoc, getCallStack) 19 | 20 | import TextShow.Classes (TextShow(..)) 21 | import TextShow.Data.Char () 22 | import TextShow.Data.Integral () 23 | import TextShow.Data.List () 24 | import TextShow.Data.Tuple () 25 | import TextShow.TH.Internal (deriveTextShow) 26 | 27 | -- | /Since: 3.0.1/ 28 | $(deriveTextShow ''SrcLoc) 29 | 30 | -- | /Since: 3.0.1/ 31 | instance TextShow CallStack where 32 | showb = showb . getCallStack 33 | {-# INLINE showb #-} 34 | -------------------------------------------------------------------------------- /tests/Spec/Data/Type/EqualitySpec.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE TypeOperators #-} 2 | 3 | {-| 4 | Module: Spec.Data.Type.EqualitySpec 5 | Copyright: (C) 2014-2017 Ryan Scott 6 | License: BSD-style (see the file LICENSE) 7 | Maintainer: Ryan Scott 8 | Stability: Provisional 9 | Portability: GHC 10 | 11 | @hspec@ test for '(:~:)'. 12 | -} 13 | module Spec.Data.Type.EqualitySpec (main, spec) where 14 | 15 | import Data.Proxy (Proxy(..)) 16 | import Data.Type.Equality.Compat 17 | 18 | import Instances.Data.Type.Equality () 19 | 20 | import Prelude () 21 | import Prelude.Compat 22 | 23 | import Test.Hspec (Spec, hspec, parallel) 24 | 25 | import Spec.Utils (matchesTextShowSpec) 26 | import Test.Hspec (describe) 27 | 28 | main :: IO () 29 | main = hspec spec 30 | 31 | spec :: Spec 32 | spec = parallel $ do 33 | describe "Int :~: Int" $ 34 | matchesTextShowSpec (Proxy :: Proxy (Int :~: Int)) 35 | describe "Int :~~: Int" $ 36 | matchesTextShowSpec (Proxy :: Proxy (Int :~~: Int)) 37 | -------------------------------------------------------------------------------- /tests/Spec/GHC/StatsSpec.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE CPP #-} 2 | {-# OPTIONS_GHC -Wno-deprecations #-} 3 | 4 | {-| 5 | Module: Spec.GHC.StatsSpec 6 | Copyright: (C) 2014-2017 Ryan Scott 7 | License: BSD-style (see the file LICENSE) 8 | Maintainer: Ryan Scott 9 | Stability: Provisional 10 | Portability: GHC 11 | 12 | @hspec@ test for 'GCStats'. 13 | -} 14 | module Spec.GHC.StatsSpec (main, spec) where 15 | 16 | import Instances.GHC.Stats () 17 | 18 | import Prelude () 19 | import Prelude.Compat 20 | 21 | import Test.Hspec (Spec, hspec, parallel) 22 | 23 | #if !(MIN_VERSION_base(4,11,0)) 24 | import Data.Proxy (Proxy(..)) 25 | import GHC.Stats (GCStats) 26 | import Spec.Utils (matchesTextShowSpec) 27 | import Test.Hspec (describe) 28 | #endif 29 | 30 | main :: IO () 31 | main = hspec spec 32 | 33 | spec :: Spec 34 | spec = parallel $ 35 | #if !(MIN_VERSION_base(4,11,0)) 36 | describe "GCStats" $ 37 | matchesTextShowSpec (Proxy :: Proxy GCStats) 38 | #else 39 | pure () 40 | #endif 41 | -------------------------------------------------------------------------------- /src/TextShow/Functions.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE OverloadedStrings #-} 2 | {-# OPTIONS_GHC -Wno-orphans #-} 3 | {-| 4 | Module: TextShow.Functions 5 | Copyright: (C) 2014-2017 Ryan Scott 6 | License: BSD-style (see the file LICENSE) 7 | Maintainer: Ryan Scott 8 | Stability: Provisional 9 | Portability: GHC 10 | 11 | Optional orphan 'TextShow', 'TextShow1', and 'TextShow2' instances for functions. 12 | 13 | /Since: 2/ 14 | -} 15 | module TextShow.Functions () where 16 | 17 | import TextShow.Classes (TextShow(..), TextShow1(..), TextShow2(..)) 18 | 19 | -- | /Since: 2/ 20 | instance TextShow (a -> b) where 21 | showbPrec = liftShowbPrec undefined undefined 22 | {-# INLINE showbPrec #-} 23 | 24 | -- | /Since: 2/ 25 | instance TextShow1 ((->) a) where 26 | liftShowbPrec = liftShowbPrec2 undefined undefined 27 | {-# INLINE liftShowbPrec #-} 28 | 29 | -- | /Since: 2/ 30 | instance TextShow2 (->) where 31 | liftShowbPrec2 _ _ _ _ _ _ = "" 32 | {-# INLINE liftShowbPrec2 #-} 33 | -------------------------------------------------------------------------------- /src/TextShow/Control/Monad/ST.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE OverloadedStrings #-} 2 | {-# OPTIONS_GHC -Wno-orphans #-} 3 | {-| 4 | Module: TextShow.Control.Monad.ST 5 | Copyright: (C) 2014-2017 Ryan Scott 6 | License: BSD-style (see the file LICENSE) 7 | Maintainer: Ryan Scott 8 | Stability: Provisional 9 | Portability: GHC 10 | 11 | 'TextShow' instance for strict 'ST'. 12 | 13 | /Since: 2/ 14 | -} 15 | module TextShow.Control.Monad.ST () where 16 | 17 | import Control.Monad.ST (ST) 18 | import TextShow.Classes (TextShow(..), TextShow1(..), TextShow2(..)) 19 | 20 | -- | /Since: 2/ 21 | instance TextShow (ST s a) where 22 | showb = liftShowbPrec undefined undefined 0 23 | {-# INLINE showb #-} 24 | 25 | -- | /Since: 2/ 26 | instance TextShow1 (ST s) where 27 | liftShowbPrec = liftShowbPrec2 undefined undefined 28 | {-# INLINE liftShowbPrec #-} 29 | 30 | -- | /Since: 2/ 31 | instance TextShow2 ST where 32 | liftShowbPrec2 _ _ _ _ _ _ = "<>" 33 | {-# INLINE liftShowbPrec2 #-} 34 | -------------------------------------------------------------------------------- /src/TextShow/GHC/Stats.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE CPP #-} 2 | 3 | #if !(MIN_VERSION_base(4,11,0)) 4 | {-# LANGUAGE TemplateHaskell #-} 5 | {-# OPTIONS_GHC -Wno-deprecations #-} 6 | {-# OPTIONS_GHC -Wno-orphans #-} 7 | # if __GLASGOW_HASKELL__ == 800 8 | -- See Note [Increased simpl-tick-factor on old GHCs] in TextShow.Data.Complex 9 | {-# OPTIONS_GHC -fsimpl-tick-factor=200 #-} 10 | # endif 11 | #endif 12 | 13 | {-| 14 | Module: TextShow.GHC.Stats 15 | Copyright: (C) 2014-2017 Ryan Scott 16 | License: BSD-style (see the file LICENSE) 17 | Maintainer: Ryan Scott 18 | Stability: Provisional 19 | Portability: GHC 20 | 21 | 'TextShow' instance for 'GCStats'. 22 | 23 | /Since: 2/ 24 | -} 25 | module TextShow.GHC.Stats () where 26 | 27 | #if !(MIN_VERSION_base(4,11,0)) 28 | import GHC.Stats (GCStats) 29 | 30 | import TextShow.Data.Integral () 31 | import TextShow.Data.Floating () 32 | import TextShow.TH.Internal (deriveTextShow) 33 | 34 | -- /Since: 2/ 35 | $(deriveTextShow ''GCStats) 36 | #endif 37 | -------------------------------------------------------------------------------- /tests/Spec/OptionsSpec.hs: -------------------------------------------------------------------------------- 1 | {-| 2 | Module: Spec.OptionsSpec 3 | Copyright: (C) 2014-2017 Ryan Scott 4 | License: BSD-style (see the file LICENSE) 5 | Maintainer: Ryan Scott 6 | Stability: Provisional 7 | Portability: GHC 8 | 9 | @hspec@ tests for 'Options' and related datatypes. 10 | -} 11 | module Spec.OptionsSpec (main, spec) where 12 | 13 | import Data.Proxy (Proxy(..)) 14 | import Instances.Options () 15 | import Spec.Utils (matchesTextShowSpec, genericTextShowSpec) 16 | import Test.Hspec (Spec, describe, hspec, parallel) 17 | import TextShow.TH (Options, GenTextMethods) 18 | 19 | main :: IO () 20 | main = hspec spec 21 | 22 | spec :: Spec 23 | spec = parallel $ do 24 | describe "Options" $ do 25 | let p :: Proxy Options 26 | p = Proxy 27 | matchesTextShowSpec p 28 | genericTextShowSpec p 29 | describe "GenTextMethods" $ do 30 | let p :: Proxy GenTextMethods 31 | p = Proxy 32 | matchesTextShowSpec p 33 | genericTextShowSpec p 34 | -------------------------------------------------------------------------------- /tests/Instances/Foreign/Ptr.hs: -------------------------------------------------------------------------------- 1 | {-# OPTIONS_GHC -Wno-orphans #-} 2 | 3 | {-| 4 | Module: Instances.Foreign.Ptr 5 | Copyright: (C) 2014-2017 Ryan Scott 6 | License: BSD-style (see the file LICENSE) 7 | Maintainer: Ryan Scott 8 | Stability: Provisional 9 | Portability: GHC 10 | 11 | 'Arbitrary' instances for pointer data types. 12 | -} 13 | module Instances.Foreign.Ptr () where 14 | 15 | import Foreign.Ptr (FunPtr, IntPtr, Ptr, WordPtr, 16 | castPtrToFunPtr, nullPtr, plusPtr, 17 | ptrToIntPtr, ptrToWordPtr) 18 | 19 | import Prelude () 20 | import Prelude.Compat 21 | 22 | import Test.QuickCheck (Arbitrary(..)) 23 | 24 | instance Arbitrary (Ptr a) where 25 | arbitrary = plusPtr nullPtr <$> arbitrary 26 | 27 | instance Arbitrary (FunPtr a) where 28 | arbitrary = castPtrToFunPtr <$> arbitrary 29 | 30 | instance Arbitrary IntPtr where 31 | arbitrary = ptrToIntPtr <$> arbitrary 32 | 33 | instance Arbitrary WordPtr where 34 | arbitrary = ptrToWordPtr <$> arbitrary 35 | -------------------------------------------------------------------------------- /tests/Spec/Data/Array/ByteSpec.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE CPP #-} 2 | 3 | {-| 4 | Module: Spec.Data.Array.ByteSpec 5 | Copyright: (C) 2022 Ryan Scott 6 | License: BSD-style (see the file LICENSE) 7 | Maintainer: Ryan Scott 8 | Stability: Provisional 9 | Portability: GHC 10 | 11 | @hspec@ tests for 'ByteArray' from the "Data.Array.Byte" module. 12 | -} 13 | module Spec.Data.Array.ByteSpec (main, spec) where 14 | 15 | import Prelude () 16 | import Prelude.Compat 17 | 18 | import Test.Hspec (Spec, hspec, parallel) 19 | import Test.QuickCheck.Instances () 20 | 21 | #if MIN_VERSION_base(4,17,0) 22 | import Data.Array.Byte (ByteArray) 23 | import Data.Proxy (Proxy(..)) 24 | 25 | import Spec.Utils (matchesTextShowSpec) 26 | 27 | import Test.Hspec (describe) 28 | #endif 29 | 30 | main :: IO () 31 | main = hspec spec 32 | 33 | spec :: Spec 34 | spec = parallel $ do 35 | #if MIN_VERSION_base(4,17,0) 36 | describe "ByteArray" $ 37 | matchesTextShowSpec (Proxy :: Proxy ByteArray) 38 | #else 39 | pure () 40 | #endif 41 | -------------------------------------------------------------------------------- /tests/Instances/Control/Concurrent.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE DeriveGeneric #-} 2 | {-# LANGUAGE StandaloneDeriving #-} 3 | {-# OPTIONS_GHC -Wno-orphans #-} 4 | 5 | {-| 6 | Module: Instances.Control.Concurrent 7 | Copyright: (C) 2014-2017 Ryan Scott 8 | License: BSD-style (see the file LICENSE) 9 | Maintainer: Ryan Scott 10 | Stability: Provisional 11 | Portability: GHC 12 | 13 | 'Arbitrary' instances for data types in the "Control.Concurrent" module. 14 | -} 15 | module Instances.Control.Concurrent () where 16 | 17 | import GHC.Conc (BlockReason(..), ThreadStatus(..)) 18 | import GHC.Generics (Generic) 19 | 20 | import Instances.Utils.GenericArbitrary (genericArbitrary) 21 | 22 | import Test.QuickCheck (Arbitrary(..), arbitraryBoundedEnum) 23 | 24 | deriving instance Bounded BlockReason 25 | deriving instance Enum BlockReason 26 | instance Arbitrary BlockReason where 27 | arbitrary = arbitraryBoundedEnum 28 | 29 | instance Arbitrary ThreadStatus where 30 | arbitrary = genericArbitrary 31 | 32 | deriving instance Generic ThreadStatus 33 | -------------------------------------------------------------------------------- /tests/Spec/GenericSpec.hs: -------------------------------------------------------------------------------- 1 | {-| 2 | Module: Spec.GenericSpec 3 | Copyright: (C) 2014-2017 Ryan Scott 4 | License: BSD-style (see the file LICENSE) 5 | Maintainer: Ryan Scott 6 | Stability: Provisional 7 | Portability: GHC 8 | 9 | @hspec@ tests for 'ConType'. 10 | -} 11 | module Spec.GenericSpec (main, spec) where 12 | 13 | import Data.Proxy (Proxy(..)) 14 | import Instances.Generic () 15 | import Instances.Utils (GenericExample) 16 | import Spec.Utils (matchesTextShowSpec, matchesTextShow1Spec, genericTextShowSpec) 17 | import Test.Hspec (Spec, describe, hspec, parallel) 18 | import TextShow.Generic (ConType) 19 | 20 | main :: IO () 21 | main = hspec spec 22 | 23 | spec :: Spec 24 | spec = parallel $ do 25 | describe "ConType" $ do 26 | let p :: Proxy ConType 27 | p = Proxy 28 | matchesTextShowSpec p 29 | genericTextShowSpec p 30 | describe "GenericExample Int" $ do 31 | let p :: Proxy (GenericExample Int) 32 | p = Proxy 33 | matchesTextShowSpec p 34 | matchesTextShow1Spec p 35 | -------------------------------------------------------------------------------- /src/TextShow/Data/List.hs: -------------------------------------------------------------------------------- 1 | {-# OPTIONS_GHC -Wno-orphans #-} 2 | {-| 3 | Module: TextShow.Data.List 4 | Copyright: (C) 2014-2017 Ryan Scott 5 | License: BSD-style (see the file LICENSE) 6 | Maintainer: Ryan Scott 7 | Stability: Provisional 8 | Portability: GHC 9 | 10 | Exports 'showbListWith', 'showtListWith', and 'showtlListWith', 11 | and 'TextShow' instances for lists. 12 | -} 13 | module TextShow.Data.List (showbListWith, showtListWith, showtlListWith) where 14 | 15 | import TextShow.Classes (TextShow(..), TextShow1(..), showbListWith, showtListWith, showtlListWith) 16 | import TextShow.Data.Char () 17 | import TextShow.Data.Integral () 18 | 19 | -- | /Since: 2/ 20 | instance TextShow a => TextShow [a] where 21 | {-# SPECIALIZE instance TextShow [String] #-} 22 | {-# SPECIALIZE instance TextShow String #-} 23 | {-# SPECIALIZE instance TextShow [Int] #-} 24 | showb = showbList 25 | {-# INLINE showb #-} 26 | 27 | -- | /Since: 2/ 28 | instance TextShow1 [] where 29 | liftShowbPrec _ sl _ = sl 30 | {-# INLINE liftShowbPrec #-} 31 | -------------------------------------------------------------------------------- /tests/Instances/GHC/Event.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE CPP #-} 2 | {-# LANGUAGE StandaloneDeriving #-} 3 | {-# OPTIONS_GHC -Wno-orphans #-} 4 | 5 | {-| 6 | Module: Instances.GHC.Event 7 | Copyright: (C) 2014-2017 Ryan Scott 8 | License: BSD-style (see the file LICENSE) 9 | Maintainer: Ryan Scott 10 | Stability: Provisional 11 | Portability: GHC 12 | 13 | 'Arbitrary' instances for data types in the "GHC.Event" module. 14 | -} 15 | module Instances.GHC.Event () where 16 | 17 | #if !defined(__GHCJS__) && !defined(ghcjs_HOST_OS) && !defined(mingw32_HOST_OS) 18 | import GHC.Event (Event, Lifetime(..), evtRead, evtWrite) 19 | 20 | import Prelude () 21 | import Prelude.Compat 22 | 23 | import Test.QuickCheck (Arbitrary(..), arbitraryBoundedEnum, oneof) 24 | 25 | instance Arbitrary Event where 26 | arbitrary = oneof $ map pure [evtRead, evtWrite] 27 | 28 | -- TODO: instance Arbitrary FdKey 29 | 30 | deriving instance Bounded Lifetime 31 | deriving instance Enum Lifetime 32 | instance Arbitrary Lifetime where 33 | arbitrary = arbitraryBoundedEnum 34 | #endif 35 | -------------------------------------------------------------------------------- /src/TextShow/Data/Functor/Identity.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE OverloadedStrings #-} 2 | {-# OPTIONS_GHC -Wno-orphans #-} 3 | {-| 4 | Module: TextShow.Data.Functor.Identity 5 | Copyright: (C) 2014-2017 Ryan Scott 6 | License: BSD-style (see the file LICENSE) 7 | Maintainer: Ryan Scott 8 | Stability: Provisional 9 | Portability: GHC 10 | 11 | 'TextShow' instance for 'Identity' values. 12 | 13 | /Since: 2/ 14 | -} 15 | module TextShow.Data.Functor.Identity () where 16 | 17 | import Data.Functor.Identity (Identity(..)) 18 | import TextShow.Classes (TextShow(..), TextShow1(..), 19 | showbPrec1, showbUnaryWith) 20 | 21 | -- | /Since: 3/ 22 | instance TextShow a => TextShow (Identity a) where 23 | showbPrec = showbPrec1 24 | {-# INLINE showbPrec #-} 25 | 26 | -- | /Since: 3/ 27 | instance TextShow1 Identity where 28 | -- This would be equivalent to the derived instance of 'Identity' if the 29 | -- 'runIdentity' field were removed. 30 | liftShowbPrec sp _ p (Identity x) = showbUnaryWith sp "Identity" p x 31 | {-# INLINE liftShowbPrec #-} 32 | -------------------------------------------------------------------------------- /src/TextShow/Data/Functor/Compose.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE OverloadedStrings #-} 2 | {-# OPTIONS_GHC -Wno-orphans #-} 3 | 4 | {-| 5 | Module: TextShow.Data.Functor.Compose 6 | Copyright: (C) 2014-2017 Ryan Scott 7 | License: BSD-style (see the file LICENSE) 8 | Maintainer: Ryan Scott 9 | Stability: Provisional 10 | Portability: GHC 11 | 12 | 'TextShow' instance for 'Compose'. 13 | 14 | /Since: 3/ 15 | -} 16 | module TextShow.Data.Functor.Compose () where 17 | 18 | import Data.Functor.Compose (Compose(..)) 19 | import TextShow.Classes (TextShow(..), TextShow1(..), showbPrec1, showbUnaryWith) 20 | 21 | -- | /Since: 3/ 22 | instance (TextShow1 f, TextShow1 g, TextShow a) => TextShow (Compose f g a) where 23 | showbPrec = showbPrec1 24 | {-# INLINE showbPrec #-} 25 | 26 | -- | /Since: 3/ 27 | instance (TextShow1 f, TextShow1 g) => TextShow1 (Compose f g) where 28 | liftShowbPrec sp sl p (Compose x) = 29 | showbUnaryWith (liftShowbPrec (liftShowbPrec sp sl) 30 | (liftShowbList sp sl)) 31 | "Compose" p x 32 | -------------------------------------------------------------------------------- /src/TextShow/Data/Data.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE TemplateHaskell #-} 2 | {-# OPTIONS_GHC -Wno-orphans #-} 3 | {-| 4 | Module: TextShow.Data.Data 5 | Copyright: (C) 2014-2017 Ryan Scott 6 | License: BSD-style (see the file LICENSE) 7 | Maintainer: Ryan Scott 8 | Stability: Provisional 9 | Portability: GHC 10 | 11 | 'TextShow' instances for data types in the @Data.Data@ module. 12 | 13 | /Since: 2/ 14 | -} 15 | module TextShow.Data.Data () where 16 | 17 | import Data.Data (Constr, ConstrRep, DataRep, DataType, Fixity, showConstr) 18 | import Data.Text.Lazy.Builder (fromString) 19 | 20 | import TextShow.Classes (TextShow(..)) 21 | import TextShow.Data.List () 22 | import TextShow.Data.Ratio () 23 | import TextShow.TH.Internal (deriveTextShow) 24 | 25 | -- | /Since: 2/ 26 | instance TextShow Constr where 27 | showb = fromString . showConstr 28 | {-# INLINE showb #-} 29 | 30 | -- | /Since: 2/ 31 | $(deriveTextShow ''DataRep) 32 | -- | /Since: 2/ 33 | $(deriveTextShow ''DataType) 34 | -- | /Since: 2/ 35 | $(deriveTextShow ''ConstrRep) 36 | -- | /Since: 2/ 37 | $(deriveTextShow ''Fixity) 38 | -------------------------------------------------------------------------------- /tests/Spec/GHC/Conc/WindowsSpec.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE CPP #-} 2 | 3 | {-| 4 | Module: Spec.GHC.Conc.WindowsSpec 5 | Copyright: (C) 2014-2017 Ryan Scott 6 | License: BSD-style (see the file LICENSE) 7 | Maintainer: Ryan Scott 8 | Stability: Provisional 9 | Portability: GHC 10 | 11 | @hspec@ test for 'ConsoleEvent'. 12 | -} 13 | module Spec.GHC.Conc.WindowsSpec (main, spec) where 14 | 15 | import Instances.GHC.Conc.Windows () 16 | 17 | import Prelude () 18 | import Prelude.Compat 19 | 20 | import Test.Hspec (Spec, hspec, parallel) 21 | 22 | #if !defined(__GHCJS__) && !defined(ghcjs_HOST_OS) && defined(mingw32_HOST_OS) 23 | import Data.Proxy (Proxy(..)) 24 | import GHC.Conc.Windows (ConsoleEvent) 25 | import Spec.Utils (matchesTextShowSpec) 26 | import Test.Hspec (describe) 27 | #endif 28 | 29 | main :: IO () 30 | main = hspec spec 31 | 32 | spec :: Spec 33 | spec = parallel $ 34 | #if !defined(__GHCJS__) && !defined(ghcjs_HOST_OS) && defined(mingw32_HOST_OS) 35 | describe "ConsoleEvent" $ 36 | matchesTextShowSpec (Proxy :: Proxy ConsoleEvent) 37 | #else 38 | pure () 39 | #endif 40 | -------------------------------------------------------------------------------- /src/TextShow/GHC/Fingerprint.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE CPP #-} 2 | {-# OPTIONS_GHC -Wno-orphans #-} 3 | {-| 4 | Module: TextShow.GHC.Fingerprint 5 | Copyright: (C) 2014-2017 Ryan Scott 6 | License: BSD-style (see the file LICENSE) 7 | Maintainer: Ryan Scott 8 | Stability: Provisional 9 | Portability: GHC 10 | 11 | 'TextShow' instance for 'Fingerprint'. 12 | 13 | /Since: 2/ 14 | -} 15 | module TextShow.GHC.Fingerprint () where 16 | 17 | import Data.Semigroup (mtimesDefault) 18 | import Data.Text.Lazy.Builder (Builder, singleton) 19 | import Data.Word (Word64) 20 | 21 | import GHC.Fingerprint.Type (Fingerprint(..)) 22 | 23 | import Prelude () 24 | import Prelude.Compat 25 | 26 | import TextShow.Classes (TextShow(..)) 27 | import TextShow.Data.Integral (showbHex) 28 | import TextShow.Utils (lengthB) 29 | 30 | -- | /Since: 2/ 31 | instance TextShow Fingerprint where 32 | showb (Fingerprint w1 w2) = hex16 w1 <> hex16 w2 33 | where 34 | hex16 :: Word64 -> Builder 35 | hex16 i = let hex = showbHex i 36 | in mtimesDefault (max 0 $ 16 - lengthB hex) (singleton '0') <> hex 37 | -------------------------------------------------------------------------------- /src/TextShow/Data/Typeable/Utils.hs: -------------------------------------------------------------------------------- 1 | {-| 2 | Module: TextShow.Data.Typeable.Utils 3 | Copyright: (C) 2014-2017 Ryan Scott 4 | License: BSD-style (see the file LICENSE) 5 | Maintainer: Ryan Scott 6 | Stability: Provisional 7 | Portability: GHC 8 | 9 | Utility functions for showing data types in the @Typeable@ module. 10 | -} 11 | module TextShow.Data.Typeable.Utils (showbArgs, showbTuple) where 12 | 13 | import Data.Text.Lazy.Builder (Builder, singleton) 14 | 15 | import Prelude () 16 | import Prelude.Compat 17 | 18 | import TextShow.Classes (TextShow(..)) 19 | 20 | -- | Helper function for showing a list of arguments, each separated by the given 21 | -- 'Builder'. 22 | showbArgs :: TextShow a => Builder -> [a] -> Builder 23 | showbArgs _ [] = mempty 24 | showbArgs _ [a] = showbPrec 10 a 25 | showbArgs sep (a:as) = showbPrec 10 a <> sep <> showbArgs sep as 26 | 27 | -- | Helper function for showing a list of 'Show' instances in a tuple. 28 | showbTuple :: TextShow a => [a] -> Builder 29 | showbTuple args = singleton '(' <> showbArgs (singleton ',') args <> singleton ')' 30 | {-# INLINE showbTuple #-} 31 | -------------------------------------------------------------------------------- /tests/Spec/Derived/TypeSynonymsSpec.hs: -------------------------------------------------------------------------------- 1 | {-| 2 | Module: Spec.Derived.TypeSynonymsSpec 3 | Copyright: (C) 2014-2017 Ryan Scott 4 | License: BSD-style (see the file LICENSE) 5 | Maintainer: Ryan Scott 6 | Stability: Provisional 7 | Portability: GHC 8 | 9 | @hspec@ tests for data types that use type synonyms. 10 | -} 11 | module Spec.Derived.TypeSynonymsSpec (main, spec) where 12 | 13 | import Data.Proxy (Proxy(..)) 14 | import Derived.TypeSynonyms 15 | import Spec.Utils (matchesTextShowSpec, genericTextShowSpec, genericTextShow1Spec) 16 | import Test.Hspec (Spec, describe, hspec, parallel) 17 | 18 | main :: IO () 19 | main = hspec spec 20 | 21 | spec :: Spec 22 | spec = parallel $ do 23 | describe "TyCon Int Int" $ do 24 | let p :: Proxy (TyCon Int Int) 25 | p = Proxy 26 | matchesTextShowSpec p 27 | genericTextShowSpec p 28 | genericTextShow1Spec p 29 | describe "TyFamily Int Int" $ do 30 | let p :: Proxy (TyFamily Int Int) 31 | p = Proxy 32 | matchesTextShowSpec p 33 | genericTextShowSpec p 34 | genericTextShow1Spec p 35 | -------------------------------------------------------------------------------- /src/TextShow/Data/Proxy.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE CPP #-} 2 | {-# LANGUAGE OverloadedStrings #-} 3 | {-# LANGUAGE PolyKinds #-} 4 | {-# LANGUAGE TemplateHaskell #-} 5 | 6 | {-# OPTIONS_GHC -Wno-orphans #-} 7 | 8 | {-| 9 | Module: TextShow.Data.Proxy 10 | Copyright: (C) 2014-2017 Ryan Scott 11 | License: BSD-style (see the file LICENSE) 12 | Maintainer: Ryan Scott 13 | Stability: Provisional 14 | Portability: GHC 15 | 16 | 'TextShow' instance for 'Proxy'. 17 | 18 | /Since: 2/ 19 | -} 20 | module TextShow.Data.Proxy () where 21 | 22 | import Data.Proxy (Proxy) 23 | 24 | import TextShow.Classes (TextShow(..)) 25 | import TextShow.TH.Internal (deriveTextShow1, makeShowbPrec, 26 | makeShowtPrec, makeShowtlPrec) 27 | 28 | -- | /Since: 2/ 29 | instance TextShow (Proxy s) where 30 | showbPrec = $(makeShowbPrec ''Proxy) 31 | showtPrec = $(makeShowtPrec ''Proxy) 32 | showtlPrec = $(makeShowtlPrec ''Proxy) 33 | {-# INLINE showbPrec #-} 34 | {-# INLINE showtPrec #-} 35 | {-# INLINE showtlPrec #-} 36 | 37 | -- | /Since: 2/ 38 | $(deriveTextShow1 ''Proxy) 39 | -------------------------------------------------------------------------------- /tests/Instances/Text/Read.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE DataKinds #-} 2 | {-# LANGUAGE FlexibleInstances #-} 3 | {-# LANGUAGE TemplateHaskell #-} 4 | {-# LANGUAGE TypeFamilies #-} 5 | {-# LANGUAGE TypeSynonymInstances #-} 6 | {-# OPTIONS_GHC -Wno-orphans #-} 7 | 8 | {-| 9 | Module: Instances.Text.Read 10 | Copyright: (C) 2014-2017 Ryan Scott 11 | License: BSD-style (see the file LICENSE) 12 | Maintainer: Ryan Scott 13 | Stability: Provisional 14 | Portability: GHC 15 | 16 | 'Arbitrary' instances for data types in the "Text.Read" module. 17 | -} 18 | module Instances.Text.Read () where 19 | 20 | import qualified Generics.Deriving.TH as Generics (deriveAll0) 21 | import Instances.Utils.GenericArbitrary (genericArbitrary) 22 | import Test.QuickCheck (Arbitrary(..)) 23 | import Text.Read (Lexeme(..)) 24 | import Text.Read.Lex (Number) 25 | 26 | $(Generics.deriveAll0 ''Lexeme) 27 | $(Generics.deriveAll0 ''Number) 28 | 29 | instance Arbitrary Lexeme where 30 | arbitrary = genericArbitrary 31 | 32 | instance Arbitrary Number where 33 | arbitrary = genericArbitrary 34 | -------------------------------------------------------------------------------- /tests/Spec/Data/CharSpec.hs: -------------------------------------------------------------------------------- 1 | {-| 2 | Module: Spec.Data.CharSpec 3 | Copyright: (C) 2014-2017 Ryan Scott 4 | License: BSD-style (see the file LICENSE) 5 | Maintainer: Ryan Scott 6 | Stability: Provisional 7 | Portability: GHC 8 | 9 | @hspec@ tests for data types in the "Data.Char" module. 10 | -} 11 | module Spec.Data.CharSpec (main, spec) where 12 | 13 | import Data.Array (elems) 14 | import Data.Char (GeneralCategory) 15 | import Data.Proxy (Proxy(..)) 16 | 17 | import GHC.Show (asciiTab) 18 | 19 | import Instances.Data.Char () 20 | 21 | import Spec.Utils (matchesTextShowSpec) 22 | 23 | import Test.Hspec (Spec, describe, hspec, it, parallel, shouldBe) 24 | 25 | import TextShow (fromString) 26 | import TextShow.Data.Char (asciiTabB) 27 | 28 | main :: IO () 29 | main = hspec spec 30 | 31 | spec :: Spec 32 | spec = parallel $ do 33 | describe "Char" $ 34 | matchesTextShowSpec (Proxy :: Proxy Char) 35 | describe "GeneralCategory" $ 36 | matchesTextShowSpec (Proxy :: Proxy GeneralCategory) 37 | describe "asciiTabB" $ 38 | it "equals asciiTab" $ map fromString asciiTab `shouldBe` elems asciiTabB 39 | -------------------------------------------------------------------------------- /tests/Spec/Data/DataSpec.hs: -------------------------------------------------------------------------------- 1 | {-| 2 | Module: Spec.Data.DataSpec 3 | Copyright: (C) 2014-2017 Ryan Scott 4 | License: BSD-style (see the file LICENSE) 5 | Maintainer: Ryan Scott 6 | Stability: Provisional 7 | Portability: GHC 8 | 9 | @hspec@ tests for data types in the "Data.Data" module. 10 | -} 11 | module Spec.Data.DataSpec (main, spec) where 12 | 13 | import Data.Data (Constr, ConstrRep, DataRep, DataType, Fixity) 14 | import Data.Proxy (Proxy(..)) 15 | 16 | import Instances.Data.Data () 17 | 18 | import Spec.Utils (matchesTextShowSpec) 19 | 20 | import Test.Hspec (Spec, describe, hspec, parallel) 21 | 22 | main :: IO () 23 | main = hspec spec 24 | 25 | spec :: Spec 26 | spec = parallel $ do 27 | describe "Constr" $ 28 | matchesTextShowSpec (Proxy :: Proxy Constr) 29 | describe "ConstrRep" $ 30 | matchesTextShowSpec (Proxy :: Proxy ConstrRep) 31 | describe "DataRep" $ 32 | matchesTextShowSpec (Proxy :: Proxy DataRep) 33 | describe "DataType" $ 34 | matchesTextShowSpec (Proxy :: Proxy DataType) 35 | describe "Fixity" $ 36 | matchesTextShowSpec (Proxy :: Proxy Fixity) 37 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | clone_folder: "c:\\WORK" 2 | 3 | environment: 4 | global: 5 | CABOPTS: "--store-dir=C:\\SR --http-transport=plain-http --enable-tests --enable-benchmarks" 6 | matrix: 7 | - GHCVER: "9.2.2" 8 | - GHCVER: "9.0.2" 9 | - GHCVER: "8.10.7" 10 | - GHCVER: "8.8.4.1" 11 | - GHCVER: "8.6.5" 12 | - GHCVER: "8.4.4" 13 | # We deliberately do not test any versions older than GHC 9.4, as GHC 8.2 14 | # is unable to build text-2.0 on Windows. See the discussion at 15 | # https://github.com/haskell/text/pull/404. 16 | 17 | cache: 18 | - "C:\\SR" 19 | 20 | install: 21 | - ps: Set-Service wuauserv -StartupType Manual 22 | - "choco install -y cabal" 23 | - "choco install -y ghc --version %GHCVER%" 24 | - "refreshenv" 25 | - "set PATH=C:\\msys64\\mingw64\\bin;C:\\msys64\\usr\\bin;%PATH%" 26 | - "cabal --version" 27 | - "ghc --version" 28 | - "cabal %CABOPTS% update -v" 29 | 30 | build: off 31 | 32 | test_script: 33 | - IF EXIST configure.ac bash -c "autoreconf -i" 34 | - "cabal %CABOPTS% new-build -j2 --enable-tests --enable-benchmarks all" 35 | - "cabal %CABOPTS% new-test -j2 --enable-tests --enable-benchmarks all" 36 | -------------------------------------------------------------------------------- /tests/Spec/Control/ApplicativeSpec.hs: -------------------------------------------------------------------------------- 1 | {-| 2 | Module: Spec.Control.ApplicativeSpec 3 | Copyright: (C) 2014-2017 Ryan Scott 4 | License: BSD-style (see the file LICENSE) 5 | Maintainer: Ryan Scott 6 | Stability: Provisional 7 | Portability: GHC 8 | 9 | @hspec@ tests for data types in the "Control.Applicative" module. 10 | -} 11 | module Spec.Control.ApplicativeSpec (main, spec) where 12 | 13 | import Control.Applicative (Const, ZipList) 14 | import Control.Monad.Trans.Instances () 15 | 16 | import Data.Orphans () 17 | import Data.Proxy (Proxy(..)) 18 | 19 | import Spec.Utils (matchesTextShowSpec, matchesTextShow1Spec, 20 | genericTextShowSpec, genericTextShow1Spec) 21 | 22 | import Test.Hspec (Spec, describe, hspec, parallel) 23 | 24 | main :: IO () 25 | main = hspec spec 26 | 27 | spec :: Spec 28 | spec = parallel $ do 29 | describe "Const Int Int" $ 30 | matchesTextShow1Spec (Proxy :: Proxy (Const Int Int)) 31 | describe "ZipList Int" $ do 32 | let p :: Proxy (ZipList Int) 33 | p = Proxy 34 | matchesTextShowSpec p 35 | genericTextShowSpec p 36 | genericTextShow1Spec p 37 | -------------------------------------------------------------------------------- /tests/Spec/Data/ArraySpec.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE CPP #-} 2 | 3 | {-| 4 | Module: Spec.Data.ArraySpec 5 | Copyright: (C) 2014-2017 Ryan Scott 6 | License: BSD-style (see the file LICENSE) 7 | Maintainer: Ryan Scott 8 | Stability: Provisional 9 | Portability: GHC 10 | 11 | @hspec@ tests for array data types. 12 | -} 13 | module Spec.Data.ArraySpec (main, spec) where 14 | 15 | import Prelude () 16 | import Prelude.Compat 17 | 18 | import Test.Hspec (Spec, hspec, parallel) 19 | import Test.QuickCheck.Instances () 20 | 21 | #if !defined(mingw32_HOST_OS) 22 | import Data.Array (Array) 23 | import Data.Array.Unboxed (UArray) 24 | import Data.Proxy (Proxy(..)) 25 | 26 | import Spec.Utils (matchesTextShowSpec) 27 | 28 | import Test.Hspec (describe) 29 | #endif 30 | 31 | main :: IO () 32 | main = hspec spec 33 | 34 | spec :: Spec 35 | spec = parallel $ do 36 | #if !defined(mingw32_HOST_OS) 37 | -- TODO: Figure out why these tests diverge on Windows 38 | describe "Array Int Int" $ 39 | matchesTextShowSpec (Proxy :: Proxy (Array Int Int)) 40 | describe "UArray Int Int" $ 41 | matchesTextShowSpec (Proxy :: Proxy (UArray Int Int)) 42 | #else 43 | pure () 44 | #endif 45 | -------------------------------------------------------------------------------- /tests/Spec/Data/ByteStringSpec.hs: -------------------------------------------------------------------------------- 1 | {-| 2 | Module: Spec.Data.ByteStringSpec 3 | Copyright: (C) 2014-2017 Ryan Scott 4 | License: BSD-style (see the file LICENSE) 5 | Maintainer: Ryan Scott 6 | Stability: Provisional 7 | Portability: GHC 8 | 9 | @hspec@ tests for data types in the @bytestring@ library. 10 | -} 11 | module Spec.Data.ByteStringSpec (main, spec) where 12 | 13 | import qualified Data.ByteString as BS (ByteString) 14 | import qualified Data.ByteString.Lazy as BL (ByteString) 15 | import Data.ByteString.Short (ShortByteString) 16 | import Data.Proxy (Proxy(..)) 17 | 18 | import Spec.Utils (matchesTextShowSpec) 19 | 20 | import Test.Hspec (Spec, describe, hspec, parallel) 21 | import Test.QuickCheck.Instances () 22 | 23 | main :: IO () 24 | main = hspec spec 25 | 26 | spec :: Spec 27 | spec = parallel $ do 28 | describe "strict ByteString" $ 29 | matchesTextShowSpec (Proxy :: Proxy BS.ByteString) 30 | describe "lazy ByteString" $ 31 | matchesTextShowSpec (Proxy :: Proxy BL.ByteString) 32 | describe "ShortByteString" $ 33 | matchesTextShowSpec (Proxy :: Proxy ShortByteString) 34 | -------------------------------------------------------------------------------- /src/TextShow/Data/Type/Equality.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE GADTs #-} 2 | {-# LANGUAGE PolyKinds #-} 3 | {-# LANGUAGE TemplateHaskell #-} 4 | {-# LANGUAGE TypeOperators #-} 5 | {-# OPTIONS_GHC -Wno-orphans #-} 6 | {-| 7 | Module: TextShow.Data.Type.Equality 8 | Copyright: (C) 2014-2017 Ryan Scott 9 | License: BSD-style (see the file LICENSE) 10 | Maintainer: Ryan Scott 11 | Stability: Provisional 12 | Portability: GHC 13 | 14 | 'TextShow' instance for propositional equality. 15 | 16 | /Since: 2/ 17 | -} 18 | module TextShow.Data.Type.Equality () where 19 | 20 | import Data.Type.Equality.Compat 21 | 22 | import TextShow.Classes (TextShow1(..)) 23 | import TextShow.TH.Internal (deriveTextShow, deriveTextShow2, makeLiftShowbPrec) 24 | 25 | -- | /Since: 2/ 26 | $(deriveTextShow ''(:~:)) 27 | 28 | -- | /Since: 2/ 29 | instance TextShow1 ((:~:) a) where 30 | liftShowbPrec = $(makeLiftShowbPrec ''(:~:)) 31 | 32 | -- | /Since: 2/ 33 | $(deriveTextShow2 ''(:~:)) 34 | 35 | -- | /Since: 3.6/ 36 | $(deriveTextShow ''(:~~:)) 37 | 38 | -- | /Since: 3.6/ 39 | instance TextShow1 ((:~~:) a) where 40 | liftShowbPrec = $(makeLiftShowbPrec ''(:~~:)) 41 | 42 | -- | /Since: 3.6/ 43 | $(deriveTextShow2 ''(:~~:)) 44 | -------------------------------------------------------------------------------- /tests/Instances/FromStringTextShow.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE FlexibleContexts #-} 2 | {-# LANGUAGE GeneralizedNewtypeDeriving #-} 3 | {-# LANGUAGE StandaloneDeriving #-} 4 | {-# OPTIONS_GHC -Wno-orphans #-} 5 | 6 | {-| 7 | Module: Instances.FromStringTextShow 8 | Copyright: (C) 2014-2017 Ryan Scott 9 | License: BSD-style (see the file LICENSE) 10 | Maintainer: Ryan Scott 11 | Stability: Provisional 12 | Portability: GHC 13 | 14 | 'Arbitrary' instances 'FromStringShow' and 'FromTextShow' 15 | -} 16 | module Instances.FromStringTextShow () where 17 | 18 | import Test.QuickCheck (Arbitrary) 19 | import TextShow (FromStringShow(..), FromTextShow(..), 20 | FromStringShow1(..), FromStringShow2(..), 21 | FromTextShow1(..), FromTextShow2(..)) 22 | 23 | deriving instance Arbitrary a => Arbitrary (FromStringShow a) 24 | deriving instance Arbitrary (f a) => Arbitrary (FromStringShow1 f a) 25 | deriving instance Arbitrary (f a b) => Arbitrary (FromStringShow2 f a b) 26 | deriving instance Arbitrary a => Arbitrary (FromTextShow a) 27 | deriving instance Arbitrary (f a) => Arbitrary (FromTextShow1 f a) 28 | deriving instance Arbitrary (f a b) => Arbitrary (FromTextShow2 f a b) 29 | -------------------------------------------------------------------------------- /src/TextShow/Data/Ratio.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE OverloadedStrings #-} 2 | {-# OPTIONS_GHC -Wno-orphans #-} 3 | 4 | {-| 5 | Module: TextShow.Data.Ratio 6 | Copyright: (C) 2014-2017 Ryan Scott 7 | License: BSD-style (see the file LICENSE) 8 | Maintainer: Ryan Scott 9 | Stability: Provisional 10 | Portability: GHC 11 | 12 | 'TextShow' instance for 'Ratio'. 13 | 14 | /Since: 2/ 15 | -} 16 | module TextShow.Data.Ratio () where 17 | 18 | import GHC.Real (Ratio(..), ratioPrec, ratioPrec1) 19 | 20 | import Prelude () 21 | import Prelude.Compat 22 | 23 | import TextShow.Classes (TextShow(..), TextShow1(..), showbParen) 24 | import TextShow.Data.Integral () 25 | 26 | -- | /Since: 2/ 27 | instance TextShow a => TextShow (Ratio a) where 28 | {-# SPECIALIZE instance TextShow Rational #-} 29 | showbPrec p (numer :% denom) = showbParen (p > ratioPrec) $ 30 | showbPrec ratioPrec1 numer 31 | <> " % " 32 | <> showbPrec ratioPrec1 denom 33 | {-# INLINE showbPrec #-} 34 | 35 | -- | /Since: 2/ 36 | instance TextShow1 Ratio where 37 | liftShowbPrec sp _ p (numer :% denom) = showbParen (p > ratioPrec) $ 38 | sp ratioPrec1 numer 39 | <> " % " 40 | <> sp ratioPrec1 denom 41 | {-# INLINE liftShowbPrec #-} 42 | -------------------------------------------------------------------------------- /tests/Spec/GHC/EventSpec.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE CPP #-} 2 | 3 | {-| 4 | Module: Spec.GHC.EventSpec 5 | Copyright: (C) 2014-2017 Ryan Scott 6 | License: BSD-style (see the file LICENSE) 7 | Maintainer: Ryan Scott 8 | Stability: Provisional 9 | Portability: GHC 10 | 11 | @hspec@ tests for data types in the "GHC.Event" module. 12 | -} 13 | module Spec.GHC.EventSpec (main, spec) where 14 | 15 | import Instances.GHC.Event () 16 | 17 | import Prelude () 18 | import Prelude.Compat 19 | 20 | import Test.Hspec (Spec, hspec, parallel) 21 | 22 | #if !defined(__GHCJS__) && !defined(ghcjs_HOST_OS) && !defined(mingw32_HOST_OS) 23 | import Data.Proxy (Proxy(..)) 24 | 25 | import GHC.Event (Event, Lifetime) 26 | 27 | import Spec.Utils (matchesTextShowSpec) 28 | 29 | import Test.Hspec (describe) 30 | #endif 31 | 32 | 33 | main :: IO () 34 | main = hspec spec 35 | 36 | spec :: Spec 37 | spec = parallel $ do 38 | #if !defined(__GHCJS__) && !defined(ghcjs_HOST_OS) && !defined(mingw32_HOST_OS) 39 | describe "Event" $ 40 | matchesTextShowSpec (Proxy :: Proxy Event) 41 | -- describe "FdKey" $ 42 | -- matchesTextShowSpec (Proxy :: Proxy FdKey) 43 | describe "Lifetime" $ 44 | matchesTextShowSpec (Proxy :: Proxy Lifetime) 45 | #else 46 | pure () 47 | #endif 48 | -------------------------------------------------------------------------------- /src/TextShow/Data/Ord.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE OverloadedStrings #-} 2 | {-# LANGUAGE TemplateHaskell #-} 3 | {-# OPTIONS_GHC -Wno-orphans #-} 4 | {-| 5 | Module: TextShow.Data.Ord 6 | Copyright: (C) 2014-2017 Ryan Scott 7 | License: BSD-style (see the file LICENSE) 8 | Maintainer: Ryan Scott 9 | Stability: Provisional 10 | Portability: GHC 11 | 12 | 'TextShow' instances for 'Ordering' and 'Down'. 13 | 14 | /Since: 2/ 15 | -} 16 | module TextShow.Data.Ord () where 17 | 18 | import GHC.Exts (Down(..)) 19 | 20 | import TextShow.Classes ( TextShow(..), TextShow1(..) 21 | , showbPrec1, showbUnaryWith ) 22 | import TextShow.TH.Internal (deriveTextShow) 23 | 24 | -- | This instance would be equivalent to a derived 'TextShow' instance 25 | -- if the 'getDown' field were removed. 26 | -- 27 | -- /Since: 2/ 28 | instance TextShow a => TextShow (Down a) where 29 | showbPrec = showbPrec1 30 | {-# INLINE showbPrec #-} 31 | 32 | -- | This instance would be equivalent to a derived 'TextShow1' instance 33 | -- if the 'getDown' field were removed. 34 | -- 35 | -- /Since: 2/ 36 | instance TextShow1 Down where 37 | liftShowbPrec sp _ p (Down x) = showbUnaryWith sp "Down" p x 38 | {-# INLINE liftShowbPrec #-} 39 | 40 | -- | /Since: 2/ 41 | $(deriveTextShow ''Ordering) 42 | -------------------------------------------------------------------------------- /tests/Spec/Derived/RecordsSpec.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE CPP #-} 2 | #if __GLASGOW_HASKELL__ == 800 3 | -- See Note [Increased simpl-tick-factor on old GHCs] in TextShow.Data.Complex 4 | {-# OPTIONS_GHC -fsimpl-tick-factor=200 #-} 5 | #endif 6 | 7 | {-| 8 | Module: Spec.Derived.RecordsSpec 9 | Copyright: (C) 2014-2017 Ryan Scott 10 | License: BSD-style (see the file LICENSE) 11 | Maintainer: Ryan Scott 12 | Stability: Provisional 13 | Portability: GHC 14 | 15 | @hspec@ tests for data types with record syntax. 16 | -} 17 | module Spec.Derived.RecordsSpec (main, spec) where 18 | 19 | import Data.Proxy (Proxy(..)) 20 | import Derived.Records 21 | import Spec.Utils (matchesTextShow1Spec, genericTextShowSpec, genericTextShow1Spec) 22 | import Test.Hspec (Spec, describe, hspec, parallel) 23 | 24 | main :: IO () 25 | main = hspec spec 26 | 27 | spec :: Spec 28 | spec = parallel $ do 29 | describe "TyCon Int Int" $ do 30 | let p :: Proxy (TyCon Int Int) 31 | p = Proxy 32 | matchesTextShow1Spec p 33 | genericTextShowSpec p 34 | genericTextShow1Spec p 35 | describe "TyFamily Int Int" $ do 36 | let p :: Proxy (TyFamily Int Int) 37 | p = Proxy 38 | matchesTextShow1Spec p 39 | genericTextShowSpec p 40 | genericTextShow1Spec p 41 | -------------------------------------------------------------------------------- /tests/Spec/Data/SemigroupSpec.hs: -------------------------------------------------------------------------------- 1 | {-| 2 | Module: Spec.Data.SemigroupSpec 3 | Copyright: (C) 2014-2017 Ryan Scott 4 | License: BSD-style (see the file LICENSE) 5 | Maintainer: Ryan Scott 6 | Stability: Provisional 7 | Portability: GHC 8 | 9 | @hspec@ tests for data types in the "Data.Semigroup" module. 10 | -} 11 | module Spec.Data.SemigroupSpec (main, spec) where 12 | 13 | import Data.Proxy (Proxy(..)) 14 | import Data.Semigroup (Min, Max, First, Last, WrappedMonoid, Arg) 15 | 16 | import Instances.Data.Semigroup () 17 | 18 | import Spec.Utils (matchesTextShowSpec) 19 | 20 | import Test.Hspec (Spec, describe, hspec, parallel) 21 | import Test.QuickCheck.Instances () 22 | 23 | main :: IO () 24 | main = hspec spec 25 | 26 | spec :: Spec 27 | spec = parallel $ do 28 | describe "Min Int" $ 29 | matchesTextShowSpec (Proxy :: Proxy (Min Int)) 30 | describe "Max Int" $ 31 | matchesTextShowSpec (Proxy :: Proxy (Max Int)) 32 | describe "First Int" $ 33 | matchesTextShowSpec (Proxy :: Proxy (First Int)) 34 | describe "Last Int" $ 35 | matchesTextShowSpec (Proxy :: Proxy (Last Int)) 36 | describe "WrappedMonoid ()" $ 37 | matchesTextShowSpec (Proxy :: Proxy (WrappedMonoid ())) 38 | describe "Arg Int Char" $ 39 | matchesTextShowSpec (Proxy :: Proxy (Arg Int Char)) 40 | -------------------------------------------------------------------------------- /tests/Instances/GHC/Stack.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE CPP #-} 2 | {-# LANGUAGE DeriveGeneric #-} 3 | {-# LANGUAGE StandaloneDeriving #-} 4 | {-# OPTIONS_GHC -Wno-orphans #-} 5 | 6 | {-| 7 | Module: Instances.GHC.Stack 8 | Copyright: (C) 2014-2017 Ryan Scott 9 | License: BSD-style (see the file LICENSE) 10 | Maintainer: Ryan Scott 11 | Stability: Provisional 12 | Portability: GHC 13 | 14 | 'Arbitrary' instances for 'CallStack' and 'SrcLoc'. 15 | -} 16 | module Instances.GHC.Stack () where 17 | 18 | import GHC.Stack.Types (CallStack(..), SrcLoc(..)) 19 | import Instances.Utils ((<@>)) 20 | import Test.QuickCheck (oneof) 21 | 22 | #if !(MIN_VERSION_base(4,15,0)) 23 | import GHC.Generics (Generic) 24 | #endif 25 | 26 | import Instances.Utils.GenericArbitrary (genericArbitrary) 27 | 28 | import Test.QuickCheck (Arbitrary(..)) 29 | 30 | #if !(MIN_VERSION_base(4,15,0)) 31 | deriving instance Generic SrcLoc 32 | #endif 33 | 34 | instance Arbitrary CallStack where 35 | arbitrary = oneof [ pure EmptyCallStack 36 | , PushCallStack <$> arbitrary <*> arbitrary <@> EmptyCallStack 37 | , pure $ FreezeCallStack EmptyCallStack 38 | ] 39 | 40 | instance Arbitrary SrcLoc where 41 | arbitrary = genericArbitrary 42 | -------------------------------------------------------------------------------- /tests/Spec/Data/ListSpec.hs: -------------------------------------------------------------------------------- 1 | {-| 2 | Module: Spec.Data.ListSpec 3 | Copyright: (C) 2014-2017 Ryan Scott 4 | License: BSD-style (see the file LICENSE) 5 | Maintainer: Ryan Scott 6 | Stability: Provisional 7 | Portability: GHC 8 | 9 | @hspec@ tests for lists. 10 | -} 11 | module Spec.Data.ListSpec (main, spec) where 12 | 13 | import Data.Proxy (Proxy(..)) 14 | 15 | import Spec.Utils (matchesTextShowSpec) 16 | 17 | import Test.Hspec (Expectation, Spec, describe, hspec, parallel, shouldBe) 18 | import Test.Hspec.QuickCheck (prop) 19 | 20 | import Text.Show (showListWith) 21 | import TextShow (fromString, showb) 22 | import TextShow.Data.List (showbListWith) 23 | 24 | main :: IO () 25 | main = hspec spec 26 | 27 | spec :: Spec 28 | spec = parallel $ do 29 | describe "String" $ 30 | matchesTextShowSpec (Proxy :: Proxy String) 31 | describe "[String]" $ 32 | matchesTextShowSpec (Proxy :: Proxy [String]) 33 | describe "[Int]" $ 34 | matchesTextShowSpec (Proxy :: Proxy [Int]) 35 | describe "showbListWith" $ 36 | prop "has the same output as showListWith" prop_showListWith 37 | 38 | -- | Verifies 'showListWith' and 'showbListWith' generate the same output. 39 | prop_showListWith :: String -> Expectation 40 | prop_showListWith str = fromString (showListWith shows str "") `shouldBe` showbListWith showb str 41 | -------------------------------------------------------------------------------- /src/TextShow/Data/Semigroup.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE TemplateHaskell #-} 2 | {-# OPTIONS_GHC -Wno-orphans #-} 3 | 4 | {-| 5 | Module: TextShow.Data.Semigroup 6 | Copyright: (C) 2014-2017 Ryan Scott 7 | License: BSD-style (see the file LICENSE) 8 | Maintainer: Ryan Scott 9 | Stability: Provisional 10 | Portability: GHC 11 | 12 | 'TextShow' instances for data types in the "Data.Semigroup" module. 13 | 14 | /Since: 3/ 15 | -} 16 | module TextShow.Data.Semigroup () where 17 | 18 | import Data.Semigroup (Min, Max, First, Last, WrappedMonoid, Arg) 19 | 20 | import TextShow.Data.Maybe () 21 | import TextShow.TH.Internal (deriveTextShow, deriveTextShow1, deriveTextShow2) 22 | 23 | -- | /Since: 3/ 24 | $(deriveTextShow ''Min) 25 | -- | /Since: 3/ 26 | $(deriveTextShow1 ''Min) 27 | 28 | -- | /Since: 3/ 29 | $(deriveTextShow ''Max) 30 | -- | /Since: 3/ 31 | $(deriveTextShow1 ''Max) 32 | 33 | -- | /Since: 3/ 34 | $(deriveTextShow ''First) 35 | -- | /Since: 3/ 36 | $(deriveTextShow1 ''First) 37 | 38 | -- | /Since: 3/ 39 | $(deriveTextShow ''Last) 40 | -- | /Since: 3/ 41 | $(deriveTextShow1 ''Last) 42 | 43 | -- | /Since: 3/ 44 | $(deriveTextShow ''WrappedMonoid) 45 | -- | /Since: 3/ 46 | $(deriveTextShow1 ''WrappedMonoid) 47 | 48 | -- | /Since: 3/ 49 | $(deriveTextShow ''Arg) 50 | -- | /Since: 3/ 51 | $(deriveTextShow1 ''Arg) 52 | -- | /Since: 3/ 53 | $(deriveTextShow2 ''Arg) 54 | -------------------------------------------------------------------------------- /src/TextShow/Numeric/Natural.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE CPP #-} 2 | {-# LANGUAGE MagicHash #-} 3 | {-# OPTIONS_GHC -Wno-orphans #-} 4 | {-| 5 | Module: TextShow.Numeric.Natural 6 | Copyright: (C) 2014-2017 Ryan Scott 7 | License: BSD-style (see the file LICENSE) 8 | Maintainer: Ryan Scott 9 | Stability: Provisional 10 | Portability: GHC 11 | 12 | 'TextShow' instance for 'Natural'. 13 | 14 | /Since: 2/ 15 | -} 16 | module TextShow.Numeric.Natural () where 17 | 18 | #if MIN_VERSION_base(4,15,0) 19 | import GHC.Exts (Word(..)) 20 | import GHC.Num (integerFromNatural) 21 | import GHC.Num.Natural (Natural(..)) 22 | #elif defined(MIN_VERSION_integer_gmp) 23 | import GHC.Exts (Word(..)) 24 | import GHC.Integer.GMP.Internals (Integer(..)) 25 | import GHC.Natural (Natural(..)) 26 | #else 27 | import Numeric.Natural (Natural) 28 | #endif 29 | 30 | import TextShow.Classes (TextShow(..)) 31 | import TextShow.Data.Integral () 32 | 33 | -- | /Since: 2/ 34 | instance TextShow Natural where 35 | #if MIN_VERSION_base(4,15,0) 36 | showbPrec p (NS w) = showbPrec p (W# w) 37 | showbPrec p n = showbPrec p (integerFromNatural n) 38 | #elif defined(MIN_VERSION_integer_gmp) 39 | showbPrec _ (NatS# w#) = showb $ W# w# 40 | showbPrec p (NatJ# bn) = showbPrec p $ Jp# bn 41 | #else 42 | showbPrec p = showbPrec p . toInteger 43 | {-# INLINE showbPrec #-} 44 | #endif 45 | -------------------------------------------------------------------------------- /src/TextShow/Data/Version.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE TemplateHaskell #-} 2 | {-# OPTIONS_GHC -Wno-orphans #-} 3 | {-| 4 | Module: TextShow.Data.Version 5 | Copyright: (C) 2014-2017 Ryan Scott 6 | License: BSD-style (see the file LICENSE) 7 | Maintainer: Ryan Scott 8 | Stability: Provisional 9 | Portability: GHC 10 | 11 | Provides a 'TextShow' instance for 'Version' and the 'showbVersion' function. 12 | 13 | /Since: 2/ 14 | -} 15 | module TextShow.Data.Version (showbVersion) where 16 | 17 | import Data.List (intersperse) 18 | import Data.Text.Lazy.Builder (Builder, fromString, singleton) 19 | import Data.Version (Version(..)) 20 | 21 | import Prelude () 22 | import Prelude.Compat 23 | 24 | import TextShow.Classes (TextShow(..)) 25 | import TextShow.Data.Char () 26 | import TextShow.Data.Integral () 27 | import TextShow.Data.List () 28 | import TextShow.TH.Internal (deriveTextShow) 29 | 30 | -- | Provides one possible concrete representation for 'Version'. For 31 | -- a version with 'versionBranch' @= [1,2,3]@ and 'versionTags' 32 | -- @= [\"tag1\",\"tag2\"]@, the output will be @1.2.3-tag1-tag2@. 33 | -- 34 | -- /Since: 3.6/ 35 | showbVersion :: Version -> Builder 36 | showbVersion (Version branch tags) 37 | = mconcat (intersperse (singleton '.') $ map showb branch) <> 38 | mconcat (map ((singleton '-' <>) . fromString) tags) 39 | {-# INLINE showbVersion #-} 40 | 41 | -- | /Since: 2/ 42 | $(deriveTextShow ''Version) 43 | -------------------------------------------------------------------------------- /src/TextShow/Debug/Trace/Generic.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE FlexibleContexts #-} 2 | 3 | {-| 4 | Module: TextShow.Debug.Trace.Generic 5 | Copyright: (C) 2014-2017 Ryan Scott 6 | License: BSD-style (see the file LICENSE) 7 | Maintainer: Ryan Scott 8 | Stability: Provisional 9 | Portability: GHC 10 | 11 | Functions that trace the values of 'Generic' instances (even if they are not 12 | instances of @TextShow@). 13 | 14 | /Since: 2/ 15 | -} 16 | module TextShow.Debug.Trace.Generic ( 17 | genericTraceTextShow 18 | , genericTraceTextShowId 19 | , genericTraceTextShowM 20 | ) where 21 | 22 | import GHC.Generics (Generic, Rep) 23 | 24 | import Prelude () 25 | import Prelude.Compat 26 | 27 | import TextShow.Debug.Trace 28 | import TextShow.Generic (GTextShowT, genericShowt) 29 | 30 | -- | A 'Generic' implementation of 'traceTextShow'. 31 | -- 32 | -- /Since: 2/ 33 | genericTraceTextShow :: (Generic a, GTextShowT (Rep a ())) => a -> b -> b 34 | genericTraceTextShow = tracet . genericShowt 35 | 36 | -- | A 'Generic' implementation of 'traceTextShowId'. 37 | -- 38 | -- /Since: 2/ 39 | genericTraceTextShowId :: (Generic a, GTextShowT (Rep a ())) => a -> a 40 | genericTraceTextShowId a = tracet (genericShowt a) a 41 | 42 | -- | A 'Generic' implementation of 'traceShowM'. 43 | -- 44 | -- /Since: 2/ 45 | genericTraceTextShowM :: (Generic a, GTextShowT (Rep a ()), Applicative f) => a -> f () 46 | genericTraceTextShowM = tracetM . genericShowt 47 | -------------------------------------------------------------------------------- /tests/Spec/Control/ConcurrentSpec.hs: -------------------------------------------------------------------------------- 1 | {-| 2 | Module: Spec.Control.ConcurrentSpec 3 | Copyright: (C) 2014-2017 Ryan Scott 4 | License: BSD-style (see the file LICENSE) 5 | Maintainer: Ryan Scott 6 | Stability: Provisional 7 | Portability: GHC 8 | 9 | @hspec@ tests for data types in the "Control.Concurrent" module. 10 | -} 11 | module Spec.Control.ConcurrentSpec (main, spec) where 12 | 13 | import Control.Concurrent (myThreadId) 14 | 15 | import Data.Proxy (Proxy(..)) 16 | 17 | import GHC.Conc (BlockReason, ThreadStatus) 18 | 19 | import Instances.Control.Concurrent () 20 | 21 | import Prelude () 22 | import Prelude.Compat 23 | 24 | import Spec.Utils (matchesTextShowSpec, prop_matchesTextShow) 25 | 26 | import Test.Hspec (Spec, describe, hspec, parallel) 27 | import Test.Hspec.QuickCheck (prop) 28 | import Test.QuickCheck (Property, ioProperty) 29 | 30 | main :: IO () 31 | main = hspec spec 32 | 33 | spec :: Spec 34 | spec = parallel $ do 35 | describe "BlockReason" $ 36 | matchesTextShowSpec (Proxy :: Proxy BlockReason) 37 | describe "ThreadId" $ 38 | prop "TextShow instance" prop_showThreadId 39 | describe "ThreadStatus" $ 40 | matchesTextShowSpec (Proxy :: Proxy ThreadStatus) 41 | 42 | -- | Verifies the 'Show' instance for 'ThreadId' is accurate. 43 | prop_showThreadId :: Int -> Property 44 | prop_showThreadId p = ioProperty $ do 45 | tid <- myThreadId 46 | pure $ prop_matchesTextShow p tid 47 | -------------------------------------------------------------------------------- /tests/Instances/Data/Data.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE DeriveGeneric #-} 2 | {-# LANGUAGE StandaloneDeriving #-} 3 | {-# OPTIONS_GHC -Wno-orphans #-} 4 | 5 | {-| 6 | Module: Instances.Data.Data 7 | Copyright: (C) 2014-2017 Ryan Scott 8 | License: BSD-style (see the file LICENSE) 9 | Maintainer: Ryan Scott 10 | Stability: Provisional 11 | Portability: GHC 12 | 13 | 'Arbitrary' instances for data types in the "Data.Data" module. 14 | -} 15 | module Instances.Data.Data () where 16 | 17 | import Data.Data (Constr, ConstrRep(..), DataRep(..), DataType, 18 | Fixity(..), mkConstr, mkDataType) 19 | 20 | import GHC.Generics (Generic) 21 | 22 | import Instances.Utils.GenericArbitrary (genericArbitrary) 23 | 24 | import Prelude () 25 | import Prelude.Compat 26 | 27 | import Test.QuickCheck (Arbitrary(..), arbitraryBoundedEnum) 28 | 29 | instance Arbitrary Constr where 30 | arbitrary = mkConstr <$> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary 31 | 32 | instance Arbitrary ConstrRep where 33 | arbitrary = genericArbitrary 34 | 35 | instance Arbitrary DataRep where 36 | arbitrary = genericArbitrary 37 | 38 | instance Arbitrary DataType where 39 | arbitrary = mkDataType <$> arbitrary <*> arbitrary 40 | 41 | deriving instance Bounded Fixity 42 | deriving instance Enum Fixity 43 | instance Arbitrary Fixity where 44 | arbitrary = arbitraryBoundedEnum 45 | 46 | deriving instance Generic ConstrRep 47 | deriving instance Generic DataRep 48 | -------------------------------------------------------------------------------- /tests/Instances/Data/Text.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE DeriveGeneric #-} 2 | {-# LANGUAGE StandaloneDeriving #-} 3 | {-# OPTIONS_GHC -Wno-deprecations #-} 4 | {-# OPTIONS_GHC -Wno-orphans #-} 5 | 6 | {-| 7 | Module: Instances.Data.Text 8 | Copyright: (C) 2014-2017 Ryan Scott 9 | License: BSD-style (see the file LICENSE) 10 | Maintainer: Ryan Scott 11 | Stability: Provisional 12 | Portability: GHC 13 | 14 | 'Arbitrary' instances for data types in the @text@ library. 15 | -} 16 | module Instances.Data.Text () where 17 | 18 | import Data.Text.Encoding (Decoding(..)) 19 | import Data.Text.Encoding.Error (UnicodeException(..)) 20 | import Data.Text.Internal.Fusion.Size (Size, exactSize) 21 | import Data.Text.Lazy.Builder (Builder, fromString) 22 | 23 | import GHC.Generics (Generic) 24 | 25 | import Instances.Utils ((<@>)) 26 | import Instances.Utils.GenericArbitrary (genericArbitrary) 27 | 28 | import Prelude () 29 | import Prelude.Compat 30 | 31 | import Test.QuickCheck (Arbitrary(..), getNonNegative) 32 | import Test.QuickCheck.Instances () 33 | 34 | instance Arbitrary Builder where 35 | arbitrary = fromString <$> arbitrary 36 | 37 | instance Arbitrary UnicodeException where 38 | arbitrary = genericArbitrary 39 | 40 | instance Arbitrary Decoding where 41 | arbitrary = Some <$> arbitrary <*> arbitrary <@> undefined 42 | 43 | instance Arbitrary Size where 44 | arbitrary = exactSize . getNonNegative <$> arbitrary 45 | 46 | deriving instance Generic UnicodeException 47 | -------------------------------------------------------------------------------- /tests/Spec/Data/TextSpec.hs: -------------------------------------------------------------------------------- 1 | {-| 2 | Module: Spec.Data.TextSpec 3 | Copyright: (C) 2014-2017 Ryan Scott 4 | License: BSD-style (see the file LICENSE) 5 | Maintainer: Ryan Scott 6 | Stability: Provisional 7 | Portability: GHC 8 | 9 | @hspec@ tests for data types in the @text@ library. 10 | -} 11 | module Spec.Data.TextSpec (main, spec) where 12 | 13 | import Data.Proxy (Proxy(..)) 14 | 15 | import Instances.Data.Text () 16 | 17 | import Spec.Utils (matchesTextShowSpec) 18 | 19 | import Test.Hspec (Spec, describe, hspec, parallel) 20 | 21 | import qualified Data.Text as TS 22 | import qualified Data.Text as TL 23 | import Data.Text.Encoding (Decoding) 24 | import Data.Text.Encoding.Error (UnicodeException) 25 | import Data.Text.Internal.Fusion.Size (Size) 26 | import Data.Text.Lazy.Builder (Builder) 27 | 28 | main :: IO () 29 | main = hspec spec 30 | 31 | spec :: Spec 32 | spec = parallel $ do 33 | describe "Builder" $ 34 | matchesTextShowSpec (Proxy :: Proxy Builder) 35 | describe "strict Text" $ 36 | matchesTextShowSpec (Proxy :: Proxy TS.Text) 37 | describe "lazy Text" $ 38 | matchesTextShowSpec (Proxy :: Proxy TL.Text) 39 | describe "UnicodeException" $ 40 | matchesTextShowSpec (Proxy :: Proxy UnicodeException) 41 | describe "Decoding" $ 42 | matchesTextShowSpec (Proxy :: Proxy Decoding) 43 | describe "Size" $ 44 | matchesTextShowSpec (Proxy :: Proxy Size) 45 | -------------------------------------------------------------------------------- /tests/Spec/GHC/TypeLitsSpec.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE CPP #-} 2 | {-# LANGUAGE DataKinds #-} 3 | 4 | {-| 5 | Module: Spec.GHC.TypeLitsSpec 6 | Copyright: (C) 2014-2017 Ryan Scott 7 | License: BSD-style (see the file LICENSE) 8 | Maintainer: Ryan Scott 9 | Stability: Provisional 10 | Portability: GHC 11 | 12 | @hspec@ tests for data types in the "GHC.TypeLits" module. 13 | -} 14 | module Spec.GHC.TypeLitsSpec (main, spec) where 15 | 16 | import Data.Proxy (Proxy(..)) 17 | 18 | import GHC.TypeLits 19 | 20 | import Instances.GHC.TypeLits () 21 | 22 | import Prelude () 23 | import Prelude.Compat 24 | 25 | import Spec.Utils (matchesTextShowSpec) 26 | #if MIN_VERSION_base(4,18,0) 27 | import Spec.Utils (Some) 28 | #endif 29 | 30 | import Test.Hspec (Spec, describe, hspec, parallel) 31 | 32 | main :: IO () 33 | main = hspec spec 34 | 35 | spec :: Spec 36 | spec = parallel $ do 37 | describe "SomeNat" $ 38 | matchesTextShowSpec (Proxy :: Proxy SomeNat) 39 | describe "SomeSymbol" $ 40 | matchesTextShowSpec (Proxy :: Proxy SomeSymbol) 41 | #if MIN_VERSION_base(4,16,0) 42 | describe "SomeChar" $ 43 | matchesTextShowSpec (Proxy :: Proxy SomeChar) 44 | #endif 45 | #if MIN_VERSION_base(4,18,0) 46 | describe "Some SNat" $ 47 | matchesTextShowSpec (Proxy :: Proxy (Some SNat)) 48 | describe "Some SSymbol" $ 49 | matchesTextShowSpec (Proxy :: Proxy (Some SSymbol)) 50 | describe "Some SChar" $ 51 | matchesTextShowSpec (Proxy :: Proxy (Some SChar)) 52 | #endif 53 | -------------------------------------------------------------------------------- /tests/Spec/Derived/InfixSpec.hs: -------------------------------------------------------------------------------- 1 | {-| 2 | Module: Spec.Derived.InfixSpec 3 | Copyright: (C) 2014-2017 Ryan Scott 4 | License: BSD-style (see the file LICENSE) 5 | Maintainer: Ryan Scott 6 | Stability: Provisional 7 | Portability: GHC 8 | 9 | @hspec@ tests for data types with infix constructors. 10 | -} 11 | module Spec.Derived.InfixSpec (main, spec) where 12 | 13 | import Data.Proxy (Proxy(..)) 14 | import Derived.Infix 15 | import Spec.Utils (matchesTextShowSpec, genericTextShowSpec, genericTextShow1Spec) 16 | import Test.Hspec (Spec, describe, hspec, parallel) 17 | 18 | main :: IO () 19 | main = hspec spec 20 | 21 | spec :: Spec 22 | spec = parallel $ do 23 | describe "TyConPlain Int Int" $ do 24 | let p :: Proxy (TyConPlain Int Int) 25 | p = Proxy 26 | matchesTextShowSpec p 27 | genericTextShowSpec p 28 | genericTextShow1Spec p 29 | describe "TyConGADT Int Int" $ do 30 | let p :: Proxy (TyConGADT Int Int) 31 | p = Proxy 32 | matchesTextShowSpec p 33 | genericTextShowSpec p 34 | genericTextShow1Spec p 35 | describe "TyFamilyPlain Int Int" $ do 36 | let p :: Proxy (TyFamilyPlain Int Int) 37 | p = Proxy 38 | matchesTextShowSpec p 39 | genericTextShowSpec p 40 | genericTextShow1Spec p 41 | describe "TyFamilyGADT Int Int" $ do 42 | let p :: Proxy (TyFamilyGADT Int Int) 43 | p = Proxy 44 | matchesTextShowSpec p 45 | genericTextShowSpec p 46 | genericTextShow1Spec p 47 | -------------------------------------------------------------------------------- /tests/Spec/Foreign/PtrSpec.hs: -------------------------------------------------------------------------------- 1 | {-| 2 | Module: Spec.Foreign.PtrSpec 3 | Copyright: (C) 2014-2017 Ryan Scott 4 | License: BSD-style (see the file LICENSE) 5 | Maintainer: Ryan Scott 6 | Stability: Provisional 7 | Portability: GHC 8 | 9 | @hspec@ tests for pointer data types. 10 | -} 11 | module Spec.Foreign.PtrSpec (main, spec) where 12 | 13 | import Data.Proxy (Proxy(..)) 14 | 15 | import Foreign.ForeignPtr (newForeignPtr_) 16 | import Foreign.Ptr (FunPtr, IntPtr, Ptr, WordPtr) 17 | 18 | import Instances.Foreign.Ptr () 19 | 20 | import Prelude () 21 | import Prelude.Compat 22 | 23 | import Spec.Utils (matchesTextShowSpec, prop_matchesTextShow) 24 | 25 | import Test.Hspec (Spec, describe, hspec, parallel) 26 | import Test.Hspec.QuickCheck (prop) 27 | import Test.QuickCheck (Property, ioProperty) 28 | 29 | main :: IO () 30 | main = hspec spec 31 | 32 | spec :: Spec 33 | spec = parallel $ do 34 | describe "Ptr Int" $ 35 | matchesTextShowSpec (Proxy :: Proxy (Ptr Int)) 36 | describe "FunPtr Int" $ 37 | matchesTextShowSpec (Proxy :: Proxy (FunPtr Int)) 38 | describe "IntPtr" $ 39 | matchesTextShowSpec (Proxy :: Proxy IntPtr) 40 | describe "WordPtr" $ 41 | matchesTextShowSpec (Proxy :: Proxy WordPtr) 42 | describe "ForeignPtr" $ 43 | prop "TextShow instance" prop_showForeignPtr 44 | 45 | -- | Verifies the 'Show' instance for 'ForeignPtr' is accurate. 46 | prop_showForeignPtr :: Int -> Ptr Int -> Property 47 | prop_showForeignPtr p ptr = ioProperty $ do 48 | fptr <- newForeignPtr_ ptr 49 | pure $ prop_matchesTextShow p fptr 50 | -------------------------------------------------------------------------------- /src/TextShow/Control/Applicative.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE CPP #-} 2 | {-# LANGUAGE OverloadedStrings #-} 3 | {-# LANGUAGE PolyKinds #-} 4 | {-# LANGUAGE TemplateHaskell #-} 5 | 6 | {-# OPTIONS_GHC -Wno-orphans #-} 7 | {-| 8 | Module: TextShow.Control.Applicative 9 | Copyright: (C) 2014-2017 Ryan Scott 10 | License: BSD-style (see the file LICENSE) 11 | Maintainer: Ryan Scott 12 | Stability: Provisional 13 | Portability: GHC 14 | 15 | 'TextShow' instances for 'Const' and 'ZipList'. 16 | 17 | /Since: 2/ 18 | -} 19 | module TextShow.Control.Applicative () where 20 | 21 | import Control.Applicative (Const(..), ZipList) 22 | 23 | import Data.Text.Lazy.Builder (Builder) 24 | 25 | import TextShow.Classes (TextShow(..), TextShow1(..), 26 | TextShow2(..), showbUnaryWith) 27 | import TextShow.Data.List () 28 | import TextShow.TH.Internal (deriveTextShow, deriveTextShow1) 29 | 30 | -- | /Since: 2/ 31 | instance TextShow a => TextShow (Const a b) where 32 | showbPrec = liftShowbConstPrec showbPrec 33 | 34 | -- | /Since: 2/ 35 | instance TextShow a => TextShow1 (Const a) where 36 | liftShowbPrec _ _ = liftShowbConstPrec showbPrec 37 | 38 | -- | /Since: 2/ 39 | instance TextShow2 Const where 40 | liftShowbPrec2 sp _ _ _ = liftShowbConstPrec sp 41 | 42 | liftShowbConstPrec :: (Int -> a -> Builder) -> Int -> Const a b -> Builder 43 | liftShowbConstPrec sp p (Const x) = showbUnaryWith sp "Const" p x 44 | {-# INLINE liftShowbConstPrec #-} 45 | 46 | -- | /Since: 2/ 47 | $(deriveTextShow ''ZipList) 48 | -- | /Since: 2/ 49 | $(deriveTextShow1 ''ZipList) 50 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014-2017, Ryan Scott 2 | 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 11 | * Redistributions in binary form must reproduce the above 12 | copyright notice, this list of conditions and the following 13 | disclaimer in the documentation and/or other materials provided 14 | with the distribution. 15 | 16 | * Neither the name of Ryan Scott nor the names of other 17 | contributors may be used to endorse or promote products derived 18 | from this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | -------------------------------------------------------------------------------- /tests/Derived/TypeFamilies.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE GeneralizedNewtypeDeriving #-} 2 | {-# LANGUAGE TemplateHaskell #-} 3 | {-# LANGUAGE TypeFamilies #-} 4 | 5 | {-| 6 | Module: Derived.TypeFamilies 7 | Copyright: (C) 2020 Ryan Scott 8 | License: BSD-style (see the file LICENSE) 9 | Maintainer: Ryan Scott 10 | Stability: Provisional 11 | Portability: GHC 12 | 13 | Defines corner case-provoking type families. 14 | -} 15 | module Derived.TypeFamilies ( 16 | TyConOverSat(..) 17 | , TyFamilyOverSat(..) 18 | ) where 19 | 20 | import Test.QuickCheck (Arbitrary) 21 | 22 | import Text.Show.Deriving (deriveShow1, deriveShow2) 23 | 24 | import TextShow.TH (deriveTextShow, deriveTextShow1, deriveTextShow2) 25 | 26 | ------------------------------------------------------------------------------- 27 | 28 | type family F :: * -> * -> * 29 | type instance F = Either 30 | 31 | newtype TyConOverSat a b = TyConOverSat (F a b) 32 | deriving (Arbitrary, Show) 33 | 34 | data family TyFamilyOverSat (x :: *) (y :: *) 35 | newtype instance TyFamilyOverSat a b = TyFamilyOverSat (F a b) 36 | deriving (Arbitrary, Show) 37 | 38 | ------------------------------------------------------------------------------- 39 | 40 | $(deriveShow1 ''TyConOverSat) 41 | $(deriveShow2 ''TyConOverSat) 42 | 43 | $(deriveShow1 'TyFamilyOverSat) 44 | $(deriveShow2 'TyFamilyOverSat) 45 | 46 | $(deriveTextShow ''TyConOverSat) 47 | $(deriveTextShow1 ''TyConOverSat) 48 | $(deriveTextShow2 ''TyConOverSat) 49 | 50 | $(deriveTextShow 'TyFamilyOverSat) 51 | $(deriveTextShow1 'TyFamilyOverSat) 52 | $(deriveTextShow2 'TyFamilyOverSat) 53 | -------------------------------------------------------------------------------- /src/TextShow/Debug/Trace/TH.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE TemplateHaskell #-} 2 | {-| 3 | Module: TextShow.Debug.Trace.TH 4 | Copyright: (C) 2014-2017 Ryan Scott 5 | License: BSD-style (see the file LICENSE) 6 | Maintainer: Ryan Scott 7 | Stability: Provisional 8 | Portability: GHC 9 | 10 | Functions that splice traces into source code which take an arbitrary data type or 11 | data family instance as an argument (even if it is not an instance of @TextShow@). You 12 | need to enable the @TemplateHaskell@ language extension in order to use this module. 13 | 14 | /Since: 2/ 15 | -} 16 | module TextShow.Debug.Trace.TH ( 17 | makeTraceTextShow 18 | , makeTraceTextShowId 19 | , makeTraceTextShowM 20 | ) where 21 | 22 | import Language.Haskell.TH.Syntax (Name, Q, Exp) 23 | 24 | import TextShow.Debug.Trace 25 | import TextShow.TH.Internal (makeShowt) 26 | 27 | -- | Generates a lambda expression which behaves like 'traceTextShow' (without 28 | -- requiring a @TextShow@ instance). 29 | -- 30 | -- /Since: 2/ 31 | makeTraceTextShow :: Name -> Q Exp 32 | makeTraceTextShow name = [| tracet . $(makeShowt name) |] 33 | 34 | -- | Generates a lambda expression which behaves like 'traceTextShowId' (without 35 | -- requiring a @TextShow@ instance). 36 | -- 37 | -- /Since: 2/ 38 | makeTraceTextShowId :: Name -> Q Exp 39 | makeTraceTextShowId name = [| \a -> tracet ($(makeShowt name) a) a |] 40 | 41 | -- | Generates a lambda expression which behaves like 'traceTextShowM' (without 42 | -- requiring a @TextShow@ instance). 43 | -- 44 | -- /Since: 2/ 45 | makeTraceTextShowM :: Name -> Q Exp 46 | makeTraceTextShowM name = [| tracetM . $(makeShowt name) |] 47 | -------------------------------------------------------------------------------- /tests/Instances/GHC/TypeLits.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE CPP #-} 2 | {-# LANGUAGE PolyKinds #-} 3 | {-# OPTIONS_GHC -Wno-orphans #-} 4 | 5 | {-| 6 | Module: Instances.GHC.TypeLits 7 | Copyright: (C) 2014-2017 Ryan Scott 8 | License: BSD-style (see the file LICENSE) 9 | Maintainer: Ryan Scott 10 | Stability: Provisional 11 | Portability: GHC 12 | 13 | 'Arbitrary' instances for data types in the "GHC.TypeLits" module. 14 | -} 15 | module Instances.GHC.TypeLits () where 16 | 17 | import GHC.TypeLits 18 | 19 | import Prelude () 20 | import Prelude.Compat 21 | 22 | import Test.QuickCheck (Arbitrary(..), getNonNegative) 23 | import Test.QuickCheck.Instances () 24 | 25 | #if MIN_VERSION_base(4,18,0) 26 | import qualified GHC.TypeNats as TN 27 | import Spec.Utils (GArbitrary(..), Some(..)) 28 | #endif 29 | 30 | instance Arbitrary SomeNat where 31 | arbitrary = do 32 | nat <- getNonNegative <$> arbitrary 33 | case someNatVal nat of 34 | Just sn -> pure sn 35 | Nothing -> error "Negative natural number" -- Should never happen 36 | 37 | instance Arbitrary SomeSymbol where 38 | arbitrary = someSymbolVal <$> arbitrary 39 | 40 | #if MIN_VERSION_base(4,16,0) 41 | instance Arbitrary SomeChar where 42 | arbitrary = someCharVal <$> arbitrary 43 | #endif 44 | 45 | #if MIN_VERSION_base(4,18,0) 46 | instance GArbitrary SNat where 47 | garbitrary = do 48 | n <- arbitrary 49 | TN.withSomeSNat n (pure . Some) 50 | 51 | instance GArbitrary SSymbol where 52 | garbitrary = do 53 | s <- arbitrary 54 | withSomeSSymbol s (pure . Some) 55 | 56 | instance GArbitrary SChar where 57 | garbitrary = do 58 | c <- arbitrary 59 | withSomeSChar c (pure . Some) 60 | #endif 61 | -------------------------------------------------------------------------------- /tests/Spec/Derived/MagicHashSpec.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE CPP #-} 2 | {-# LANGUAGE MagicHash #-} 3 | #if __GLASGOW_HASKELL__ == 800 4 | -- See Note [Increased simpl-tick-factor on old GHCs] in TextShow.Data.Complex 5 | {-# OPTIONS_GHC -fsimpl-tick-factor=250 #-} 6 | #endif 7 | 8 | {-| 9 | Module: Spec.Derived.MagicHashSpec 10 | Copyright: (C) 2014-2017 Ryan Scott 11 | License: BSD-style (see the file LICENSE) 12 | Maintainer: Ryan Scott 13 | Stability: Provisional 14 | Portability: GHC 15 | 16 | @hspec@ tests for data types with fields that have unlifted types. 17 | -} 18 | module Spec.Derived.MagicHashSpec (main, spec) where 19 | 20 | import Data.Proxy (Proxy(..)) 21 | import Derived.MagicHash 22 | import Spec.Utils 23 | import Test.Hspec (Spec, describe, hspec, parallel) 24 | 25 | main :: IO () 26 | main = hspec spec 27 | 28 | spec :: Spec 29 | spec = parallel $ do 30 | describe "TyCon# Int Int" $ do 31 | let p :: Proxy (TyCon# Int Int) 32 | p = Proxy 33 | matchesTextShow1Spec p 34 | genericTextShowSpec p 35 | genericTextShow1Spec p 36 | describe "TyFamily# Int Int" $ do 37 | let p :: Proxy (TyFamily# Int Int) 38 | p = Proxy 39 | matchesTextShow1Spec p 40 | genericTextShowSpec p 41 | genericTextShow1Spec p 42 | #if MIN_VERSION_base(4,13,0) 43 | describe "TyCon'# Int Int" $ do 44 | let p :: Proxy (TyCon'# Int Int) 45 | p = Proxy 46 | matchesTextShowSpec p 47 | matchesTextShow2Spec p 48 | describe "TyFamily'# Int Int" $ do 49 | let p :: Proxy (TyFamily'# Int Int) 50 | p = Proxy 51 | matchesTextShowSpec p 52 | matchesTextShow2Spec p 53 | #endif 54 | -------------------------------------------------------------------------------- /tests/Spec/Data/FixedSpec.hs: -------------------------------------------------------------------------------- 1 | {-| 2 | Module: Spec.Data.FixedSpec 3 | Copyright: (C) 2014-2017 Ryan Scott 4 | License: BSD-style (see the file LICENSE) 5 | Maintainer: Ryan Scott 6 | Stability: Provisional 7 | Portability: GHC 8 | 9 | @hspec@ test for 'Fixed' values. 10 | -} 11 | module Spec.Data.FixedSpec (main, spec) where 12 | 13 | import Data.Fixed (Fixed, E0, E1, E2, E3, E6, E9, E12, showFixed) 14 | import Data.Proxy (Proxy(..)) 15 | 16 | import Spec.Utils (matchesTextShowSpec) 17 | 18 | import Test.Hspec (Expectation, Spec, describe, hspec, parallel, shouldBe) 19 | import Test.Hspec.QuickCheck (prop) 20 | 21 | import TextShow (fromString) 22 | import TextShow.Data.Fixed (showbFixed) 23 | 24 | main :: IO () 25 | main = hspec spec 26 | 27 | spec :: Spec 28 | spec = parallel $ do 29 | describe "Fixed E0" $ 30 | matchesTextShowSpec (Proxy :: Proxy (Fixed E0)) 31 | describe "Fixed E1" $ 32 | matchesTextShowSpec (Proxy :: Proxy (Fixed E1)) 33 | describe "Fixed E2" $ 34 | matchesTextShowSpec (Proxy :: Proxy (Fixed E2)) 35 | describe "Fixed E3" $ 36 | matchesTextShowSpec (Proxy :: Proxy (Fixed E3)) 37 | describe "Fixed E6" $ 38 | matchesTextShowSpec (Proxy :: Proxy (Fixed E6)) 39 | describe "Fixed E9" $ 40 | matchesTextShowSpec (Proxy :: Proxy (Fixed E9)) 41 | describe "Fixed E12" $ 42 | matchesTextShowSpec (Proxy :: Proxy (Fixed E12)) 43 | describe "showbFixed" $ 44 | prop "has the same output as showFixed" prop_showFixed 45 | 46 | -- | Verifies 'showFixed' and 'showbFixed' generate the same output. 47 | prop_showFixed :: Bool -> Fixed E12 -> Expectation 48 | prop_showFixed b f = fromString (showFixed b f) `shouldBe` showbFixed b f 49 | -------------------------------------------------------------------------------- /tests/Spec/Derived/DataFamiliesSpec.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE DataKinds #-} 2 | 3 | {-| 4 | Module: Spec.Derived.DataFamiliesSpec 5 | Copyright: (C) 2014-2017 Ryan Scott 6 | License: BSD-style (see the file LICENSE) 7 | Maintainer: Ryan Scott 8 | Stability: Provisional 9 | Portability: GHC 10 | 11 | @hspec@ tests for corner case-provoking data families. 12 | -} 13 | module Spec.Derived.DataFamiliesSpec (main, spec) where 14 | 15 | import Data.Proxy (Proxy(..)) 16 | 17 | import Derived.DataFamilies (NotAllShow, KindDistinguished, NullaryData) 18 | 19 | import Prelude () 20 | import Prelude.Compat 21 | 22 | import Spec.Utils ( matchesTextShowSpec, matchesTextShow1Spec 23 | , genericTextShowSpec, genericTextShow1Spec ) 24 | 25 | import Test.Hspec (Spec, describe, hspec, parallel) 26 | 27 | main :: IO () 28 | main = hspec spec 29 | 30 | spec :: Spec 31 | spec = parallel $ do 32 | describe "NotAllShow Int Int Int Int" $ do 33 | let p :: Proxy (NotAllShow Int Int Int Int) 34 | p = Proxy 35 | matchesTextShow1Spec p 36 | genericTextShowSpec p 37 | genericTextShow1Spec p 38 | describe "KindDistinguished '() Int Int" $ do 39 | let p :: Proxy (KindDistinguished '() Int Int) 40 | p = Proxy 41 | matchesTextShow1Spec p 42 | genericTextShowSpec p 43 | genericTextShow1Spec p 44 | describe "KindDistinguished 'True Int Int" $ do 45 | let p :: Proxy (KindDistinguished 'True Int Int) 46 | p = Proxy 47 | matchesTextShow1Spec p 48 | genericTextShowSpec p 49 | genericTextShow1Spec p 50 | describe "NullaryData" $ do 51 | let p :: Proxy NullaryData 52 | p = Proxy 53 | matchesTextShowSpec p 54 | genericTextShowSpec p 55 | -------------------------------------------------------------------------------- /src/TextShow/Control/Concurrent.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE CPP #-} 2 | {-# LANGUAGE ForeignFunctionInterface #-} 3 | {-# LANGUAGE MagicHash #-} 4 | {-# LANGUAGE TemplateHaskell #-} 5 | {-# LANGUAGE UnliftedFFITypes #-} 6 | {-# OPTIONS_GHC -Wno-orphans #-} 7 | {-| 8 | Module: TextShow.Control.Concurrent 9 | Copyright: (C) 2014-2017 Ryan Scott 10 | License: BSD-style (see the file LICENSE) 11 | Maintainer: Ryan Scott 12 | Stability: Provisional 13 | Portability: GHC 14 | 15 | 'TextShow' instances for concurrency-related data types. 16 | 17 | /Since: 2/ 18 | -} 19 | module TextShow.Control.Concurrent () where 20 | 21 | import Data.Text.Lazy.Builder (fromString) 22 | 23 | import Foreign.C.Types 24 | 25 | import GHC.Conc (BlockReason, ThreadStatus) 26 | import GHC.Conc.Sync (ThreadId(..)) 27 | import GHC.Exts (Addr#, unsafeCoerce#) 28 | 29 | import Prelude () 30 | import Prelude.Compat 31 | 32 | import TextShow.Classes (TextShow(..)) 33 | import TextShow.Foreign.C.Types () 34 | import TextShow.TH.Internal (deriveTextShow) 35 | 36 | #if MIN_VERSION_base(4,14,0) 37 | import TextShow.Classes (showbParen) 38 | import GHC.Show (appPrec) 39 | #endif 40 | 41 | -- | /Since: 2/ 42 | instance TextShow ThreadId where 43 | showbPrec p t = 44 | #if MIN_VERSION_base(4,14,0) 45 | showbParen (p > appPrec) $ 46 | #endif 47 | fromString "ThreadId " <> showbPrec p (getThreadId t) 48 | {-# INLINE showbPrec #-} 49 | 50 | -- Temporary workaround until Trac #8281 is fixed 51 | foreign import ccall unsafe "rts_getThreadId" getThreadId# :: Addr# -> CInt 52 | 53 | getThreadId :: ThreadId -> CInt 54 | getThreadId (ThreadId tid) = getThreadId# (unsafeCoerce# tid) 55 | 56 | -- | /Since: 2/ 57 | $(deriveTextShow ''BlockReason) 58 | -- | /Since: 2/ 59 | $(deriveTextShow ''ThreadStatus) 60 | -------------------------------------------------------------------------------- /tests/Instances/System/IO.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE DeriveGeneric #-} 2 | {-# LANGUAGE StandaloneDeriving #-} 3 | {-# OPTIONS_GHC -Wno-orphans #-} 4 | 5 | {-| 6 | Module: Instances.System.IO 7 | Copyright: (C) 2014-2017 Ryan Scott 8 | License: BSD-style (see the file LICENSE) 9 | Maintainer: Ryan Scott 10 | Stability: Provisional 11 | Portability: GHC 12 | 13 | 'Arbitrary' instances for data types in the "System.IO" module. 14 | -} 15 | module Instances.System.IO () where 16 | 17 | import GHC.Generics (Generic) 18 | import GHC.IO.Encoding.Failure (CodingFailureMode(..)) 19 | import GHC.IO.Encoding.Types (CodingProgress(..)) 20 | import GHC.IO.Handle (HandlePosn(..)) 21 | 22 | import Instances.Utils.GenericArbitrary (genericArbitrary) 23 | 24 | import Prelude () 25 | import Prelude.Compat 26 | 27 | import System.IO (BufferMode(..), IOMode(..), SeekMode(..), Handle, 28 | stdin, stdout, stderr) 29 | 30 | import Test.QuickCheck (Arbitrary(..), arbitraryBoundedEnum, oneof) 31 | 32 | instance Arbitrary Handle where 33 | arbitrary = oneof $ map pure [stdin, stdout, stderr] 34 | 35 | instance Arbitrary HandlePosn where 36 | arbitrary = genericArbitrary 37 | 38 | deriving instance Bounded IOMode 39 | instance Arbitrary IOMode where 40 | arbitrary = arbitraryBoundedEnum 41 | 42 | instance Arbitrary BufferMode where 43 | arbitrary = genericArbitrary 44 | 45 | deriving instance Bounded SeekMode 46 | instance Arbitrary SeekMode where 47 | arbitrary = arbitraryBoundedEnum 48 | 49 | deriving instance Bounded CodingProgress 50 | deriving instance Enum CodingProgress 51 | instance Arbitrary CodingProgress where 52 | arbitrary = arbitraryBoundedEnum 53 | 54 | deriving instance Bounded CodingFailureMode 55 | deriving instance Enum CodingFailureMode 56 | instance Arbitrary CodingFailureMode where 57 | arbitrary = arbitraryBoundedEnum 58 | 59 | deriving instance Generic HandlePosn 60 | deriving instance Generic BufferMode 61 | -------------------------------------------------------------------------------- /src/TextShow/Data/Complex.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE CPP #-} 2 | {-# LANGUAGE TemplateHaskell #-} 3 | {-# OPTIONS_GHC -Wno-orphans #-} 4 | #if __GLASGOW_HASKELL__ == 800 5 | -- See Note [Increased simpl-tick-factor on old GHCs] 6 | {-# OPTIONS_GHC -fsimpl-tick-factor=200 #-} 7 | #endif 8 | 9 | {-| 10 | Module: TextShow.Data.Ratio 11 | Copyright: (C) 2014-2017 Ryan Scott 12 | License: BSD-style (see the file LICENSE) 13 | Maintainer: Ryan Scott 14 | Stability: Provisional 15 | Portability: GHC 16 | 17 | 'TextShow' instances for 'Ratio'. 18 | 19 | /Since: 2/ 20 | -} 21 | module TextShow.Data.Complex () where 22 | 23 | import Data.Complex (Complex) 24 | 25 | import TextShow.Classes (TextShow(..)) 26 | import TextShow.Data.Floating () 27 | import TextShow.TH.Internal (deriveTextShow1, makeShowbPrec) 28 | 29 | -- | /Since: 2/ 30 | instance TextShow a => TextShow (Complex a) where 31 | {-# SPECIALIZE instance TextShow (Complex Float) #-} 32 | {-# SPECIALIZE instance TextShow (Complex Double) #-} 33 | showbPrec = $(makeShowbPrec ''Complex) 34 | {-# INLINE showbPrec #-} 35 | 36 | -- | /Since: 2/ 37 | $(deriveTextShow1 ''Complex) 38 | 39 | {- 40 | Note [Increased simpl-tick-factor on old GHCs] 41 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 42 | 43 | Compiling certain text-show modules with optimizations on old versions of GHC 44 | (particularly 8.0 and 8.2) will trigger "Simplifier ticks exhausted" panics. 45 | To make things worse, this sometimes depends on whether a certain version of 46 | the text library is being used. There are two possible ways to work around 47 | this issue: 48 | 49 | 1. Figure out which uses of the INLINE pragma in text-show are responsible 50 | and remove them. 51 | 2. Just increase the tick limit. 52 | 53 | Since executing on (1) will require a lot of effort to fix an issue that only 54 | happens on old versions of GHC, I've opted for the simple solution of (2) for 55 | now. Issue #51 is a reminder to revisit this choice. 56 | -} 57 | -------------------------------------------------------------------------------- /src/TextShow/Data/Monoid.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE CPP #-} 2 | {-# LANGUAGE FlexibleContexts #-} 3 | {-# LANGUAGE TemplateHaskell #-} 4 | {-# OPTIONS_GHC -Wno-orphans #-} 5 | {-| 6 | Module: TextShow.Data.Monoid 7 | Copyright: (C) 2014-2017 Ryan Scott 8 | License: BSD-style (see the file LICENSE) 9 | Maintainer: Ryan Scott 10 | Stability: Provisional 11 | Portability: GHC 12 | 13 | 'TextShow' instances for 'Monoid'-related newtypes. 14 | 15 | /Since: 2/ 16 | -} 17 | module TextShow.Data.Monoid () where 18 | 19 | import Data.Monoid (All, Alt, Any, Dual, First, Last, Product, Sum) 20 | 21 | import TextShow.Classes (TextShow(..)) 22 | import TextShow.Data.Bool () 23 | import TextShow.Data.Maybe () 24 | import TextShow.TH.Internal (deriveTextShow, deriveTextShow1, makeShowbPrec) 25 | 26 | #if MIN_VERSION_base(4,12,0) 27 | import Data.Monoid (Ap) 28 | #endif 29 | 30 | -- | /Since: 2/ 31 | $(deriveTextShow ''All) 32 | -- | /Since: 2/ 33 | $(deriveTextShow ''Any) 34 | -- | /Since: 2/ 35 | $(deriveTextShow ''Dual) 36 | -- | /Since: 2/ 37 | $(deriveTextShow1 ''Dual) 38 | -- | /Since: 2/ 39 | $(deriveTextShow ''First) 40 | -- | /Since: 2/ 41 | $(deriveTextShow1 ''First) 42 | -- | /Since: 2/ 43 | $(deriveTextShow ''Last) 44 | -- | /Since: 2/ 45 | $(deriveTextShow1 ''Last) 46 | -- | /Since: 2/ 47 | $(deriveTextShow ''Product) 48 | -- | /Since: 2/ 49 | $(deriveTextShow1 ''Product) 50 | -- | /Since: 2/ 51 | $(deriveTextShow ''Sum) 52 | -- | /Since: 2/ 53 | $(deriveTextShow1 ''Sum) 54 | 55 | -- | /Since: 2/ 56 | instance TextShow (f a) => TextShow (Alt f a) where 57 | showbPrec = $(makeShowbPrec ''Alt) 58 | 59 | -- | /Since: 2/ 60 | $(deriveTextShow1 ''Alt) 61 | 62 | #if MIN_VERSION_base(4,12,0) 63 | -- | Only available with @base-4.12.0.0@ or later. 64 | -- 65 | -- /Since: 3.7.4/ 66 | instance TextShow (f a) => TextShow (Ap f a) where 67 | showbPrec = $(makeShowbPrec ''Ap) 68 | 69 | -- | Only available with @base-4.12.0.0@ or later. 70 | -- 71 | -- /Since: 3.7.4/ 72 | $(deriveTextShow1 ''Ap) 73 | #endif 74 | -------------------------------------------------------------------------------- /tests/Spec/BuilderSpec.hs: -------------------------------------------------------------------------------- 1 | {-| 2 | Module: Spec.BuilderSpec 3 | Copyright: (C) 2014-2017 Ryan Scott 4 | License: BSD-style (see the file LICENSE) 5 | Maintainer: Ryan Scott 6 | Stability: Provisional 7 | Portability: GHC 8 | 9 | @hspec@ tests for functions that manipulate 'Builder's. 10 | -} 11 | module Spec.BuilderSpec (main, spec) where 12 | 13 | import Instances.Data.Text () 14 | 15 | import Test.Hspec (Expectation, Spec, describe, hspec, parallel, shouldBe) 16 | import Test.Hspec.QuickCheck (prop) 17 | 18 | import TextShow (Builder, fromString, fromText, lengthB, 19 | toString, toText, unlinesB, unwordsB) 20 | 21 | main :: IO () 22 | main = hspec spec 23 | 24 | -- | Verifies 'lengthB' and 'length' produce the same output. 25 | prop_lengthB :: String -> Expectation 26 | prop_lengthB s = fromIntegral (lengthB $ fromString s) `shouldBe` length s 27 | 28 | -- | Verifies @fromText . toText = id@. 29 | prop_toText :: Builder -> Expectation 30 | prop_toText b = fromText (toText b) `shouldBe` b 31 | 32 | -- | Verifies @fromString . toString = id@. 33 | prop_toString :: Builder -> Expectation 34 | prop_toString b = fromString (toString b) `shouldBe` b 35 | 36 | -- | Verifies 'unlinesB' and 'unlines' produce the same output. 37 | prop_unlinesB :: [String] -> Expectation 38 | prop_unlinesB strs = unlinesB (map fromString strs) `shouldBe` fromString (unlines strs) 39 | 40 | -- | Verifies 'unwordsB' and 'unwords' produce the same output. 41 | prop_unwordsB :: [String] -> Expectation 42 | prop_unwordsB strs = unwordsB (map fromString strs) `shouldBe` fromString (unwords strs) 43 | 44 | spec :: Spec 45 | spec = parallel $ do 46 | describe "lengthB" $ 47 | prop "has the same output as length" prop_lengthB 48 | describe "toString" $ 49 | prop "fromString . toString = id" prop_toString 50 | describe "toText" $ 51 | prop "fromText . toText = id" prop_toText 52 | describe "unlinesB" $ 53 | prop "has the same output as unlines" prop_unlinesB 54 | describe "unwordsB" $ 55 | prop "has the same output as unwords" prop_unwordsB 56 | -------------------------------------------------------------------------------- /tests/Instances/Generic.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE CPP #-} 2 | {-# LANGUAGE DeriveGeneric #-} 3 | {-# LANGUAGE StandaloneDeriving #-} 4 | {-# LANGUAGE TemplateHaskell #-} 5 | {-# LANGUAGE TypeFamilies #-} 6 | #if __GLASGOW_HASKELL__ >= 806 7 | {-# LANGUAGE DerivingVia #-} 8 | #endif 9 | {-# OPTIONS_GHC -Wno-orphans #-} 10 | 11 | {-| 12 | Module: Instances.Generic 13 | Copyright: (C) 2014-2017 Ryan Scott 14 | License: BSD-style (see the file LICENSE) 15 | Maintainer: Ryan Scott 16 | Stability: Provisional 17 | Portability: GHC 18 | 19 | Provides instances for 'GenericExample', and an 'Arbitrary' instance for 'ConType'. 20 | -} 21 | module Instances.Generic () where 22 | 23 | import GHC.Generics (Generic, Generic1) 24 | 25 | import Instances.Data.Text () 26 | import Instances.Utils (GenericExample(..)) 27 | import Instances.Utils.GenericArbitrary (genericArbitrary) 28 | 29 | import Test.QuickCheck (Arbitrary(..)) 30 | 31 | import Text.Show.Deriving (deriveShow1) 32 | 33 | import TextShow (TextShow(..), TextShow1(..)) 34 | import TextShow.Generic ( ConType(..) 35 | #if __GLASGOW_HASKELL__ >= 806 36 | , FromGeneric(..), FromGeneric1(..) 37 | #else 38 | , genericShowbPrec, genericLiftShowbPrec 39 | #endif 40 | ) 41 | 42 | deriving instance Show a => Show (GenericExample a) 43 | $(deriveShow1 ''GenericExample) 44 | instance Arbitrary a => Arbitrary (GenericExample a) where 45 | arbitrary = genericArbitrary 46 | 47 | deriving instance Generic (GenericExample a) 48 | deriving instance Generic1 GenericExample 49 | 50 | #if __GLASGOW_HASKELL__ >= 806 51 | deriving via FromGeneric (GenericExample a) 52 | instance TextShow a => TextShow (GenericExample a) 53 | deriving via FromGeneric1 GenericExample 54 | instance TextShow1 GenericExample 55 | #else 56 | instance TextShow a => TextShow (GenericExample a) where 57 | showbPrec = genericShowbPrec 58 | 59 | instance TextShow1 GenericExample where 60 | liftShowbPrec = genericLiftShowbPrec 61 | #endif 62 | 63 | instance Arbitrary ConType where 64 | arbitrary = genericArbitrary 65 | -------------------------------------------------------------------------------- /src/TextShow/Data/Array/Byte.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE BangPatterns #-} 2 | {-# LANGUAGE CPP #-} 3 | {-# LANGUAGE MagicHash #-} 4 | {-# OPTIONS_GHC -Wno-orphans #-} 5 | {-| 6 | Module: TextShow.Data.Array.Byte 7 | Copyright: (C) 2022 Ryan Scott 8 | License: BSD-style (see the file LICENSE) 9 | Maintainer: Ryan Scott 10 | Stability: Provisional 11 | Portability: GHC 12 | 13 | Provides a 'TextShow' instance for 'ByteArray' from the "Data.Array.Byte" 14 | module. Only provided if using @base-4.17.0.0@ or later. 15 | 16 | /Since: 3.10/ 17 | -} 18 | module TextShow.Data.Array.Byte () where 19 | 20 | #if MIN_VERSION_base(4,17,0) 21 | import Data.Array.Byte (ByteArray(..)) 22 | import Data.Bits (Bits(..)) 23 | import Data.Char (intToDigit) 24 | import Data.Text.Lazy.Builder (Builder, fromString, singleton) 25 | 26 | import GHC.Exts (Int(..), indexWord8Array#, sizeofByteArray#) 27 | import GHC.Word (Word8(..)) 28 | 29 | import Prelude () 30 | import Prelude.Compat 31 | 32 | import TextShow.Classes (TextShow(..)) 33 | 34 | -- | /Since: 3.10/ 35 | instance TextShow ByteArray where 36 | showbPrec _ ba = 37 | fromString "[" <> go 0 38 | where 39 | showW8 :: Word8 -> Builder 40 | showW8 !w = 41 | singleton '0' 42 | <> singleton 'x' 43 | <> singleton (intToDigit (fromIntegral (unsafeShiftR w 4))) 44 | <> singleton (intToDigit (fromIntegral (w .&. 0x0F))) 45 | go i 46 | | i < sizeofByteArray ba = comma <> showW8 (indexByteArray ba i :: Word8) <> go (i+1) 47 | | otherwise = singleton ']' 48 | where 49 | comma | i == 0 = mempty 50 | | otherwise = fromString ", " 51 | 52 | -- | Read byte at specific index. 53 | indexByteArray :: ByteArray -> Int -> Word8 54 | {-# INLINE indexByteArray #-} 55 | indexByteArray (ByteArray arr#) (I# i#) = W8# (indexWord8Array# arr# i#) 56 | 57 | -- | Size of the byte array in bytes. 58 | sizeofByteArray :: ByteArray -> Int 59 | {-# INLINE sizeofByteArray #-} 60 | sizeofByteArray (ByteArray arr#) = I# (sizeofByteArray# arr#) 61 | #endif 62 | -------------------------------------------------------------------------------- /src/TextShow/GHC/Event.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE CPP #-} 2 | 3 | #if !defined(__GHCJS__) && !defined(ghcjs_HOST_OS) && !defined(mingw32_HOST_OS) 4 | {-# LANGUAGE OverloadedStrings #-} 5 | {-# LANGUAGE TemplateHaskell #-} 6 | {-# OPTIONS_GHC -Wno-orphans #-} 7 | #endif 8 | {-| 9 | Module: TextShow.GHC.Event 10 | Copyright: (C) 2014-2017 Ryan Scott 11 | License: BSD-style (see the file LICENSE) 12 | Maintainer: Ryan Scott 13 | Stability: Provisional 14 | Portability: GHC 15 | 16 | 'TextShow' instances for data types in the @Event@ module. 17 | Only provided if using a platform other than Windows or GHCJS. 18 | 19 | /Since: 2/ 20 | -} 21 | module TextShow.GHC.Event () where 22 | 23 | #if !defined(__GHCJS__) && !defined(ghcjs_HOST_OS) && !defined(mingw32_HOST_OS) 24 | import Data.List (intersperse) 25 | import Data.Maybe (catMaybes) 26 | import Data.Text.Lazy.Builder (Builder, singleton) 27 | 28 | import GHC.Event (Event, Lifetime, evtRead, evtWrite) 29 | 30 | import Language.Haskell.TH.Lib (conT, varE) 31 | 32 | import Prelude () 33 | import Prelude.Compat 34 | 35 | import TextShow.Classes (TextShow(..)) 36 | import TextShow.Data.Integral () 37 | import TextShow.System.Posix.Types () 38 | import TextShow.TH.Internal (deriveTextShow) 39 | import TextShow.TH.Names (evtCloseValName, eventIsValName, 40 | fdKeyTypeName, uniqueTypeName, asInt64ValName) 41 | 42 | -- | /Since: 2/ 43 | instance TextShow Event where 44 | showb e = singleton '[' <> mconcat (intersperse "," $ catMaybes 45 | [ evtRead `so` "evtRead" 46 | , evtWrite `so` "evtWrite" 47 | , $(varE evtCloseValName) `so` "evtClose" 48 | ]) <> singleton ']' 49 | where 50 | so :: Event -> Builder -> Maybe Builder 51 | ev `so` disp | $(varE eventIsValName) e ev = Just disp 52 | | otherwise = Nothing 53 | 54 | -- | /Since: 2/ 55 | $(deriveTextShow fdKeyTypeName) 56 | 57 | instance TextShow $(conT uniqueTypeName) where 58 | showb = showb . $(varE asInt64ValName) 59 | {-# INLINE showb #-} 60 | 61 | -- | /Since: 2/ 62 | $(deriveTextShow ''Lifetime) 63 | #endif 64 | -------------------------------------------------------------------------------- /tests/Spec/FromStringTextShowSpec.hs: -------------------------------------------------------------------------------- 1 | {-| 2 | Module: Spec.FromStringTextShowSpec 3 | Copyright: (C) 2014-2017 Ryan Scott 4 | License: BSD-style (see the file LICENSE) 5 | Maintainer: Ryan Scott 6 | Stability: Provisional 7 | Portability: GHC 8 | 9 | @hspec@ tests for 'FromStringShow' and 'FromTextShow'. 10 | -} 11 | module Spec.FromStringTextShowSpec (main, spec) where 12 | 13 | import Data.Proxy (Proxy(..)) 14 | import Instances.FromStringTextShow () 15 | import Spec.Utils (matchesTextShowSpec, matchesTextShow1Spec, 16 | matchesTextShow2Spec) 17 | import Test.Hspec (Spec, describe, hspec, parallel) 18 | import TextShow (FromStringShow(..), FromTextShow(..), 19 | FromStringShow1(..), FromStringShow2(..), 20 | FromTextShow1(..), FromTextShow2(..)) 21 | 22 | main :: IO () 23 | main = hspec spec 24 | 25 | spec :: Spec 26 | spec = parallel $ do 27 | describe "FromStringShow Int" $ do 28 | let p :: Proxy (FromStringShow Int) 29 | p = Proxy 30 | matchesTextShowSpec p 31 | describe "FromStringShow String" $ do 32 | let p :: Proxy (FromStringShow String) 33 | p = Proxy 34 | matchesTextShowSpec p 35 | describe "FromTextShow Int" $ do 36 | let p :: Proxy (FromTextShow Int) 37 | p = Proxy 38 | matchesTextShowSpec p 39 | describe "FromTextShow String" $ do 40 | let p :: Proxy (FromTextShow String) 41 | p = Proxy 42 | matchesTextShowSpec p 43 | describe "FromStringShow1 Maybe Int" $ do 44 | let p :: Proxy (FromStringShow1 Maybe Int) 45 | p = Proxy 46 | matchesTextShow1Spec p 47 | describe "FromTextShow1 Maybe Int" $ do 48 | let p :: Proxy (FromTextShow1 Maybe Int) 49 | p = Proxy 50 | matchesTextShow1Spec p 51 | describe "FromStringShow2 Either Char Int" $ do 52 | let p :: Proxy (FromStringShow2 Either Char Int) 53 | p = Proxy 54 | matchesTextShow2Spec p 55 | describe "FromTextShow2 Either Char Int" $ do 56 | let p :: Proxy (FromTextShow2 Either Char Int) 57 | p = Proxy 58 | matchesTextShow2Spec p 59 | -------------------------------------------------------------------------------- /src/TextShow/Data/Array.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE CPP #-} 2 | {-# LANGUAGE FlexibleContexts #-} 3 | {-# LANGUAGE OverloadedStrings #-} 4 | {-# OPTIONS_GHC -Wno-orphans #-} 5 | {-| 6 | Module: TextShow.Data.Array 7 | Copyright: (C) 2014-2017 Ryan Scott 8 | License: BSD-style (see the file LICENSE) 9 | Maintainer: Ryan Scott 10 | Stability: Provisional 11 | Portability: GHC 12 | 13 | Provides 'TextShow' instances for 'Array' types, as well as the 14 | 'showbIArrayPrec' function. 15 | 16 | /Since: 2/ 17 | -} 18 | module TextShow.Data.Array (showbIArrayPrec) where 19 | 20 | import qualified Data.Array as Array (assocs, bounds) 21 | import Data.Array (Array) 22 | import qualified Data.Array.Base as IArray (assocs, bounds) 23 | import Data.Array.Base (IArray) 24 | import Data.Array.Unboxed (UArray) 25 | import Data.Ix (Ix) 26 | import Data.Text.Lazy.Builder (Builder) 27 | 28 | import GHC.Show (appPrec) 29 | 30 | import Prelude () 31 | import Prelude.Compat 32 | 33 | import TextShow.Classes (TextShow(..), showbParen, showbSpace) 34 | import TextShow.Data.List () 35 | import TextShow.Data.Tuple () 36 | 37 | -- | Convert an 'IArray' instance to a 'Builder' with the given precedence. 38 | -- 39 | -- /Since: 2/ 40 | showbIArrayPrec :: (IArray a e, Ix i, TextShow i, TextShow e) => Int -> a i e -> Builder 41 | showbIArrayPrec p a = showbParen (p > arrayPrec) $ 42 | "array " 43 | <> showb (IArray.bounds a) 44 | <> showbSpace 45 | <> showb (IArray.assocs a) 46 | where 47 | arrayPrec :: Int 48 | #if MIN_VERSION_base(4,13,0) 49 | arrayPrec = appPrec 50 | #else 51 | arrayPrec = 9 52 | #endif 53 | 54 | -- | /Since: 2/ 55 | instance (TextShow i, TextShow e, Ix i) => TextShow (Array i e) where 56 | showbPrec p a = showbParen (p > appPrec) $ 57 | "array " 58 | <> showb (Array.bounds a) 59 | <> showbSpace 60 | <> showb (Array.assocs a) 61 | {-# INLINE showbPrec #-} 62 | 63 | -- | /Since: 2/ 64 | instance (IArray UArray e, Ix i, TextShow i, TextShow e) => TextShow (UArray i e) where 65 | showbPrec = showbIArrayPrec 66 | {-# INLINE showbPrec #-} 67 | -------------------------------------------------------------------------------- /src/TextShow/System/IO.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE OverloadedStrings #-} 2 | {-# LANGUAGE TemplateHaskell #-} 3 | {-# OPTIONS_GHC -Wno-orphans #-} 4 | {-| 5 | Module: TextShow.System.IO 6 | Copyright: (C) 2014-2017 Ryan Scott 7 | License: BSD-style (see the file LICENSE) 8 | Maintainer: Ryan Scott 9 | Stability: Provisional 10 | Portability: GHC 11 | 12 | 'TextShow' instances for 'IO'-related data types. 13 | 14 | /Since: 2/ 15 | -} 16 | module TextShow.System.IO () where 17 | 18 | import Data.Text.Lazy.Builder (Builder, fromString, singleton) 19 | 20 | import GHC.IO.Encoding.Failure (CodingFailureMode) 21 | import GHC.IO.Encoding.Types (CodingProgress, TextEncoding(textEncodingName)) 22 | import GHC.IO.Handle (HandlePosn(..)) 23 | import GHC.IO.Handle.Types (Handle(..)) 24 | 25 | import Prelude () 26 | import Prelude.Compat 27 | 28 | import System.IO (BufferMode, IOMode, Newline, NewlineMode, SeekMode) 29 | 30 | import TextShow.Classes (TextShow(..)) 31 | import TextShow.Data.Integral () 32 | import TextShow.Data.Maybe () 33 | import TextShow.TH.Internal (deriveTextShow) 34 | 35 | -- | /Since: 2/ 36 | instance TextShow Handle where 37 | showb (FileHandle file _) = showbHandleFilePath file 38 | showb (DuplexHandle file _ _) = showbHandleFilePath file 39 | {-# INLINE showb #-} 40 | 41 | -- | Convert a 'Handle`'s 'FilePath' to a 'Builder'. 42 | showbHandleFilePath :: FilePath -> Builder 43 | showbHandleFilePath file = "{handle: " <> fromString file <> singleton '}' 44 | {-# INLINE showbHandleFilePath #-} 45 | 46 | -- | /Since: 2/ 47 | $(deriveTextShow ''IOMode) 48 | -- | /Since: 2/ 49 | $(deriveTextShow ''BufferMode) 50 | 51 | -- | /Since: 2/ 52 | instance TextShow HandlePosn where 53 | showb (HandlePosn h pos) = showb h <> " at position " <> showbPrec 0 pos 54 | {-# INLINE showb #-} 55 | 56 | -- | /Since: 2/ 57 | $(deriveTextShow ''SeekMode) 58 | 59 | -- | /Since: 2/ 60 | instance TextShow TextEncoding where 61 | showb = fromString . textEncodingName 62 | {-# INLINE showb #-} 63 | 64 | -- | /Since: 2/ 65 | $(deriveTextShow ''CodingProgress) 66 | -- | /Since: 2/ 67 | $(deriveTextShow ''CodingFailureMode) 68 | -- | /Since: 2/ 69 | $(deriveTextShow ''Newline) 70 | -- | /Since: 2/ 71 | $(deriveTextShow ''NewlineMode) 72 | -------------------------------------------------------------------------------- /tests/Spec/Derived/PolyKindsSpec.hs: -------------------------------------------------------------------------------- 1 | {-| 2 | Module: Spec.Derived.PolyKindsSpec 3 | Copyright: (C) 2014-2017 Ryan Scott 4 | License: BSD-style (see the file LICENSE) 5 | Maintainer: Ryan Scott 6 | Stability: Provisional 7 | Portability: GHC 8 | 9 | @hspec@ tests for data types with poly-kinded type variables. 10 | -} 11 | module Spec.Derived.PolyKindsSpec (main, spec) where 12 | 13 | import Data.Proxy (Proxy(..)) 14 | import Derived.PolyKinds 15 | import Spec.Utils (matchesTextShow1Spec, genericTextShowSpec, genericTextShow1Spec) 16 | import Test.Hspec (Spec, describe, hspec, parallel) 17 | 18 | main :: IO () 19 | main = hspec spec 20 | 21 | spec :: Spec 22 | spec = parallel $ do 23 | describe "TyConCompose Either Either Either Maybe Maybe Int Int" $ do 24 | let p :: Proxy (TyConCompose Either Either Either Maybe Maybe Int Int) 25 | p = Proxy 26 | matchesTextShow1Spec p 27 | genericTextShowSpec p 28 | genericTextShow1Spec p 29 | describe "TyConProxy Int Int" $ do 30 | let p :: Proxy (TyConProxy Int Int) 31 | p = Proxy 32 | matchesTextShow1Spec p 33 | genericTextShowSpec p 34 | genericTextShow1Spec p 35 | describe "TyConReallyHighKinds (,,,,) Int Int Int Int Int" $ do 36 | let p :: Proxy (TyConReallyHighKinds (,,,,) Int Int Int Int Int) 37 | p = Proxy 38 | matchesTextShow1Spec p 39 | genericTextShowSpec p 40 | genericTextShow1Spec p 41 | describe "TyFamilyCompose Either Either Either Maybe Maybe Int Int" $ do 42 | let p :: Proxy (TyFamilyCompose Either Either Either Maybe Maybe Int Int) 43 | p = Proxy 44 | matchesTextShow1Spec p 45 | genericTextShowSpec p 46 | genericTextShow1Spec p 47 | describe "TyFamilyProxy Int Int" $ do 48 | let p :: Proxy (TyFamilyProxy Int Int) 49 | p = Proxy 50 | matchesTextShow1Spec p 51 | genericTextShowSpec p 52 | genericTextShow1Spec p 53 | describe "TyFamilyReallyHighKinds (,,,,) Int Int Int Int Int" $ do 54 | let p :: Proxy (TyFamilyReallyHighKinds (,,,,) Int Int Int Int Int) 55 | p = Proxy 56 | matchesTextShow1Spec p 57 | genericTextShowSpec p 58 | genericTextShow1Spec p 59 | -------------------------------------------------------------------------------- /src/TextShow/GHC/TypeLits.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE CPP #-} 2 | {-# OPTIONS_GHC -Wno-orphans #-} 3 | {-| 4 | Module: TextShow.GHC.TypeLits 5 | Copyright: (C) 2014-2017 Ryan Scott 6 | License: BSD-style (see the file LICENSE) 7 | Maintainer: Ryan Scott 8 | Stability: Provisional 9 | Portability: GHC 10 | 11 | 'TextShow' instances for data types in the @GHC.TypeLits@ module. 12 | 13 | /Since: 2/ 14 | -} 15 | module TextShow.GHC.TypeLits () where 16 | 17 | import GHC.TypeLits (SomeNat(..), SomeSymbol(..), natVal, symbolVal) 18 | #if MIN_VERSION_base(4,16,0) 19 | import GHC.TypeLits (SomeChar(..), charVal) 20 | #endif 21 | 22 | import Prelude () 23 | import Prelude.Compat 24 | 25 | import TextShow.Classes (TextShow(..)) 26 | import TextShow.Data.Char () 27 | import TextShow.Data.Integral () 28 | 29 | #if MIN_VERSION_base(4,18,0) 30 | import Data.Text.Lazy.Builder (fromString) 31 | import GHC.Show (appPrec, appPrec1) 32 | import GHC.TypeLits ( SNat, SSymbol, SChar 33 | , fromSNat, fromSSymbol, fromSChar 34 | ) 35 | import TextShow.Classes (showbParen) 36 | #endif 37 | 38 | -- | /Since: 2/ 39 | instance TextShow SomeNat where 40 | showbPrec p (SomeNat x) = showbPrec p $ natVal x 41 | {-# INLINE showbPrec #-} 42 | 43 | -- | /Since: 2/ 44 | instance TextShow SomeSymbol where 45 | showb (SomeSymbol x) = showbList $ symbolVal x 46 | {-# INLINE showb #-} 47 | 48 | #if MIN_VERSION_base(4,16,0) 49 | -- | /Since: 3.10.1/ 50 | instance TextShow SomeChar where 51 | showbPrec p (SomeChar x) = showbPrec p $ charVal x 52 | {-# INLINE showbPrec #-} 53 | #endif 54 | 55 | #if MIN_VERSION_base(4,18,0) 56 | -- | /Since: 3.10.1/ 57 | instance TextShow (SNat n) where 58 | showbPrec p sn 59 | = showbParen (p > appPrec) 60 | ( fromString "SNat @" 61 | <> showbPrec appPrec1 (fromSNat sn) 62 | ) 63 | 64 | -- | /Since: 3.10.1/ 65 | instance TextShow (SSymbol s) where 66 | showbPrec p ss 67 | = showbParen (p > appPrec) 68 | ( fromString "SSymbol @" 69 | <> showbList (fromSSymbol ss) 70 | ) 71 | 72 | -- | /Since: 3.10.1/ 73 | instance TextShow (SChar c) where 74 | showbPrec p sc 75 | = showbParen (p > appPrec) 76 | ( fromString "SChar @" 77 | <> showbPrec appPrec1 (fromSChar sc) 78 | ) 79 | #endif 80 | -------------------------------------------------------------------------------- /tests/Spec/GHC/RTS/FlagsSpec.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE CPP #-} 2 | 3 | {-| 4 | Module: Spec.GHC.RTS.Flags 5 | Copyright: (C) 2014-2017 Ryan Scott 6 | License: BSD-style (see the file LICENSE) 7 | Maintainer: Ryan Scott 8 | Stability: Provisional 9 | Portability: GHC 10 | 11 | @hspec@ tests for 'ConType'. 12 | -} 13 | module Spec.GHC.RTS.FlagsSpec (main, spec) where 14 | 15 | import Data.Proxy (Proxy(..)) 16 | 17 | import GHC.RTS.Flags 18 | 19 | import Instances.GHC.RTS.Flags 20 | 21 | import Prelude () 22 | import Prelude.Compat 23 | 24 | import Spec.Utils (matchesTextShowSpec) 25 | 26 | import Test.Hspec (Spec, describe, hspec, parallel) 27 | 28 | main :: IO () 29 | main = hspec spec 30 | 31 | spec :: Spec 32 | spec = parallel $ do 33 | describe "RTSFlags" $ 34 | matchesTextShowSpec (Proxy :: Proxy RTSFlags) 35 | describe "GCFlags" $ 36 | matchesTextShowSpec (Proxy :: Proxy GCFlags) 37 | describe "ConcFlags" $ 38 | matchesTextShowSpec (Proxy :: Proxy ConcFlags) 39 | #if MIN_VERSION_base(4,21,0) 40 | describe "IoManagerFlag" $ 41 | matchesTextShowSpec (Proxy :: Proxy IoManagerFlag) 42 | #elif MIN_VERSION_base(4,15,0) 43 | describe "IoSubSystem" $ 44 | matchesTextShowSpec (Proxy :: Proxy IoSubSystem) 45 | #endif 46 | describe "MiscFlags" $ 47 | matchesTextShowSpec (Proxy :: Proxy MiscFlags) 48 | describe "DebugFlags" $ 49 | matchesTextShowSpec (Proxy :: Proxy DebugFlags) 50 | describe "CCFlags" $ 51 | matchesTextShowSpec (Proxy :: Proxy CCFlags) 52 | describe "ProfFlags" $ 53 | matchesTextShowSpec (Proxy :: Proxy ProfFlags) 54 | describe "TraceFlags" $ 55 | matchesTextShowSpec (Proxy :: Proxy TraceFlags) 56 | describe "TickyFlags" $ 57 | matchesTextShowSpec (Proxy :: Proxy TickyFlags) 58 | describe "GiveGCStats" $ 59 | matchesTextShowSpec (Proxy :: Proxy GiveGCStats') 60 | describe "DoCostCentres" $ 61 | matchesTextShowSpec (Proxy :: Proxy DoCostCentres') 62 | describe "DoHeapProfile" $ 63 | matchesTextShowSpec (Proxy :: Proxy DoHeapProfile') 64 | describe "DoTrace" $ 65 | matchesTextShowSpec (Proxy :: Proxy DoTrace') 66 | #if MIN_VERSION_base(4,10,0) 67 | describe "ParFlags" $ 68 | matchesTextShowSpec (Proxy :: Proxy ParFlags) 69 | #endif 70 | -------------------------------------------------------------------------------- /tests/Derived/Records.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE DeriveGeneric #-} 2 | {-# LANGUAGE TemplateHaskell #-} 3 | {-# LANGUAGE TypeFamilies #-} 4 | 5 | {-| 6 | Module: Derived.Records 7 | Copyright: (C) 2014-2017 Ryan Scott 8 | License: BSD-style (see the file LICENSE) 9 | Maintainer: Ryan Scott 10 | Stability: Provisional 11 | Portability: GHC 12 | 13 | Defines data types with record syntax. 14 | -} 15 | module Derived.Records (TyCon(..), TyFamily(..)) where 16 | 17 | import GHC.Generics (Generic, Generic1) 18 | 19 | import Instances.Utils.GenericArbitrary (genericArbitrary) 20 | 21 | import Prelude () 22 | import Prelude.Compat 23 | 24 | import Test.QuickCheck (Arbitrary(..)) 25 | 26 | import Text.Show.Deriving (deriveShow1, deriveShow2) 27 | 28 | import TextShow.TH (deriveTextShow, deriveTextShow1, deriveTextShow2) 29 | 30 | ------------------------------------------------------------------------------- 31 | 32 | infixl 4 :@: 33 | data TyCon a b = TyConPrefix { tc1 :: a, tc2 :: b } 34 | | (:@:) { tc3 :: b, (##) :: a } 35 | deriving ( Show 36 | , Generic 37 | , Generic1 38 | ) 39 | 40 | ------------------------------------------------------------------------------- 41 | 42 | data family TyFamily y z :: * 43 | 44 | infixl 4 :!: 45 | data instance TyFamily a b = TyFamilyPrefix { tf1 :: a, tf2 :: b } 46 | | (:!:) { tf3 :: b, (###) :: a } 47 | deriving ( Show 48 | , Generic 49 | , Generic1 50 | ) 51 | 52 | ------------------------------------------------------------------------------- 53 | 54 | instance (Arbitrary a, Arbitrary b) => Arbitrary (TyCon a b) where 55 | arbitrary = genericArbitrary 56 | 57 | instance (Arbitrary a, Arbitrary b) => Arbitrary (TyFamily a b) where 58 | arbitrary = genericArbitrary 59 | 60 | ------------------------------------------------------------------------------- 61 | 62 | $(deriveShow1 ''TyCon) 63 | $(deriveShow2 ''TyCon) 64 | 65 | $(deriveTextShow ''TyCon) 66 | $(deriveTextShow1 ''TyCon) 67 | $(deriveTextShow2 ''TyCon) 68 | 69 | $(deriveShow1 'TyFamilyPrefix) 70 | $(deriveShow2 '(:!:)) 71 | 72 | $(deriveTextShow 'TyFamilyPrefix) 73 | $(deriveTextShow1 '(:!:)) 74 | $(deriveTextShow2 'TyFamilyPrefix) 75 | -------------------------------------------------------------------------------- /src/TextShow/Options.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE DeriveDataTypeable #-} 2 | {-# LANGUAGE DeriveGeneric #-} 3 | {-# LANGUAGE DeriveLift #-} 4 | 5 | {-| 6 | Module: TextShow.Options 7 | Copyright: (C) 2014-2017 Ryan Scott 8 | License: BSD-style (see the file LICENSE) 9 | Maintainer: Ryan Scott 10 | Stability: Provisional 11 | Portability: GHC 12 | 13 | 'Options' and related datatypes. 14 | 15 | /Since: 3.4/ 16 | -} 17 | module TextShow.Options (Options(..), GenTextMethods(..), defaultOptions) where 18 | 19 | import Data.Data (Data) 20 | import Data.Ix (Ix) 21 | 22 | import GHC.Generics (Generic) 23 | 24 | import Language.Haskell.TH.Syntax (Lift) 25 | 26 | -- | Options that specify how to derive 'TextShow' instances using Template Haskell. 27 | -- 28 | -- /Since: 3.4/ 29 | data Options = Options 30 | { genTextMethods :: GenTextMethods 31 | -- ^ When Template Haskell should generate definitions for methods which 32 | -- return @Text@? 33 | -- 34 | -- /Since: 3.4/ 35 | , emptyCaseBehavior :: Bool 36 | -- ^ If 'True', derived instances for empty data types (i.e., ones with 37 | -- no data constructors) will use the @EmptyCase@ language extension. 38 | -- If 'False', derived instances will simply use 'seq' instead. 39 | -- 40 | -- /Since: 3.7/ 41 | } deriving ( Data 42 | , Eq 43 | , Generic 44 | , Ord 45 | , Read 46 | , Show 47 | , Lift 48 | ) 49 | 50 | -- | When should Template Haskell generate implementations for the methods of 51 | -- 'TextShow' which return @Text@? 52 | -- 53 | -- /Since: 3.4/ 54 | data GenTextMethods 55 | = AlwaysTextMethods -- ^ Always generate them. 56 | | SometimesTextMethods -- ^ Only generate when @text-show@ feels it's appropriate. 57 | | NeverTextMethods -- ^ Never generate them under any circumstances. 58 | deriving ( Bounded 59 | , Data 60 | , Enum 61 | , Eq 62 | , Generic 63 | , Ix 64 | , Ord 65 | , Read 66 | , Show 67 | , Lift 68 | ) 69 | 70 | -- | Sensible default 'Options'. 71 | -- 72 | -- /Since: 3.4/ 73 | defaultOptions :: Options 74 | defaultOptions = 75 | Options { genTextMethods = SometimesTextMethods 76 | , emptyCaseBehavior = False 77 | } 78 | -------------------------------------------------------------------------------- /tests/Instances/GHC/Generics.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE FlexibleContexts #-} 2 | {-# LANGUAGE FlexibleInstances #-} 3 | {-# LANGUAGE GeneralizedNewtypeDeriving #-} 4 | {-# LANGUAGE StandaloneDeriving #-} 5 | {-# LANGUAGE TypeOperators #-} 6 | {-# LANGUAGE TypeSynonymInstances #-} 7 | {-# OPTIONS_GHC -Wno-orphans #-} 8 | 9 | {-| 10 | Module: Instances.GHC.Generics 11 | Copyright: (C) 2014-2017 Ryan Scott 12 | License: BSD-style (see the file LICENSE) 13 | Maintainer: Ryan Scott 14 | Stability: Provisional 15 | Portability: GHC 16 | 17 | 'Arbitrary' instances for data types in the "GHC.Generics" module. 18 | -} 19 | module Instances.GHC.Generics () where 20 | 21 | import Data.Orphans () 22 | import GHC.Generics 23 | import Instances.Utils.GenericArbitrary (genericArbitrary) 24 | import Test.QuickCheck (Arbitrary(..), arbitraryBoundedEnum) 25 | 26 | instance Arbitrary (U1 p) where 27 | arbitrary = genericArbitrary 28 | 29 | deriving instance Arbitrary p => Arbitrary (Par1 p) 30 | deriving instance Arbitrary (f p) => Arbitrary (Rec1 f p) 31 | deriving instance Arbitrary c => Arbitrary (K1 i c p) 32 | deriving instance Arbitrary (f p) => Arbitrary (M1 i c f p) 33 | deriving instance Arbitrary (f (g p)) => Arbitrary ((f :.: g) p) 34 | 35 | instance (Arbitrary (f p), Arbitrary (g p)) => Arbitrary ((f :+: g) p) where 36 | arbitrary = genericArbitrary 37 | 38 | instance (Arbitrary (f p), Arbitrary (g p)) => Arbitrary ((f :*: g) p) where 39 | arbitrary = genericArbitrary 40 | 41 | instance Arbitrary Fixity where 42 | arbitrary = genericArbitrary 43 | 44 | instance Arbitrary Associativity where 45 | arbitrary = arbitraryBoundedEnum 46 | 47 | instance Arbitrary SourceUnpackedness where 48 | arbitrary = arbitraryBoundedEnum 49 | 50 | instance Arbitrary SourceStrictness where 51 | arbitrary = arbitraryBoundedEnum 52 | 53 | instance Arbitrary DecidedStrictness where 54 | arbitrary = arbitraryBoundedEnum 55 | 56 | instance Arbitrary (UChar p) where 57 | arbitrary = genericArbitrary 58 | 59 | instance Arbitrary (UDouble p) where 60 | arbitrary = genericArbitrary 61 | 62 | instance Arbitrary (UFloat p) where 63 | arbitrary = genericArbitrary 64 | 65 | instance Arbitrary (UInt p) where 66 | arbitrary = genericArbitrary 67 | 68 | instance Arbitrary (UWord p) where 69 | arbitrary = genericArbitrary 70 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # `text-show` 2 | [![Hackage](https://img.shields.io/hackage/v/text-show.svg)][Hackage: text-show] 3 | [![Hackage Dependencies](https://img.shields.io/hackage-deps/v/text-show.svg)](http://packdeps.haskellers.com/reverse/text-show) 4 | [![Haskell Programming Language](https://img.shields.io/badge/language-Haskell-blue.svg)][Haskell.org] 5 | [![BSD3 License](http://img.shields.io/badge/license-BSD3-brightgreen.svg)][tl;dr Legal: BSD3] 6 | [![Linux build](https://github.com/RyanGlScott/text-show/workflows/Haskell-CI/badge.svg)](https://github.com/RyanGlScott/text-show/actions?query=workflow%3AHaskell-CI) 7 | [![Windows build](https://ci.appveyor.com/api/projects/status/fy1q86lbfttmnthy?svg=true)](https://ci.appveyor.com/project/RyanGlScott/text-show) 8 | 9 | [Hackage: text-show]: 10 | http://hackage.haskell.org/package/text-show 11 | "text-show package on Hackage" 12 | [Haskell.org]: 13 | http://www.haskell.org 14 | "The Haskell Programming Language" 15 | [tl;dr Legal: BSD3]: 16 | https://tldrlegal.com/license/bsd-3-clause-license-%28revised%29 17 | "BSD 3-Clause License (Revised)" 18 | 19 | `text-show` offers a replacement for the `Show` typeclass intended for use with `Text` instead of `String`s. This package was created in the spirit of [`bytestring-show`](http://hackage.haskell.org/package/bytestring-show). 20 | 21 | For most uses, simply importing `TextShow` will suffice: 22 | 23 | ```haskell 24 | module Main where 25 | 26 | import TextShow 27 | 28 | main :: IO () 29 | main = printT (Just "Hello, World!") 30 | ``` 31 | 32 | See also the [naming conventions](https://github.com/RyanGlScott/text-show/wiki/Naming-conventions) page. 33 | 34 | Support for automatically deriving `TextShow` instances can be found in the `TextShow.TH` and `TextShow.Generic` modules. 35 | 36 | ## Scope of the library 37 | 38 | `text-show` only provides instances for data types in the following packages: 39 | 40 | * [`array`](http://hackage.haskell.org/package/array) 41 | * [`base`](http://hackage.haskell.org/package/base) 42 | * [`bytestring`](http://hackage.haskell.org/package/bytestring) 43 | * [`text`](http://hackage.haskell.org/package/text) 44 | 45 | This policy is in place to keep `text-show`'s dependencies reasonably light. If 46 | you need a `TextShow` instance for a library that is not in this list, it may 47 | be covered by the 48 | [`text-show-instances`](https://github.com/RyanGlScott/text-show-instances) 49 | library. 50 | -------------------------------------------------------------------------------- /src/TextShow/Foreign/C/Types.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE CPP #-} 2 | {-# LANGUAGE GeneralizedNewtypeDeriving #-} 3 | {-# LANGUAGE StandaloneDeriving #-} 4 | {-# OPTIONS_GHC -Wno-orphans #-} 5 | 6 | {-| 7 | Module: TextShow.Foreign.C.Types 8 | Copyright: (C) 2014-2017 Ryan Scott 9 | License: BSD-style (see the file LICENSE) 10 | Maintainer: Ryan Scott 11 | Stability: Provisional 12 | Portability: GHC 13 | 14 | 'TextShow' instances for Haskell newtypes corresponding to C 15 | types in the Foreign Function Interface (FFI). 16 | 17 | /Since: 2/ 18 | -} 19 | module TextShow.Foreign.C.Types () where 20 | 21 | import Foreign.C.Types 22 | 23 | import TextShow.Classes (TextShow(..)) 24 | import TextShow.Data.Floating () 25 | import TextShow.Data.Integral () 26 | 27 | -- | /Since: 2/ 28 | deriving instance TextShow CChar 29 | -- | /Since: 2/ 30 | deriving instance TextShow CSChar 31 | -- | /Since: 2/ 32 | deriving instance TextShow CUChar 33 | -- | /Since: 2/ 34 | deriving instance TextShow CShort 35 | -- | /Since: 2/ 36 | deriving instance TextShow CUShort 37 | -- | /Since: 2/ 38 | deriving instance TextShow CInt 39 | -- | /Since: 2/ 40 | deriving instance TextShow CUInt 41 | -- | /Since: 2/ 42 | deriving instance TextShow CLong 43 | -- | /Since: 2/ 44 | deriving instance TextShow CULong 45 | -- | /Since: 2/ 46 | deriving instance TextShow CPtrdiff 47 | -- | /Since: 2/ 48 | deriving instance TextShow CSize 49 | -- | /Since: 2/ 50 | deriving instance TextShow CWchar 51 | -- | /Since: 2/ 52 | deriving instance TextShow CSigAtomic 53 | -- | /Since: 2/ 54 | deriving instance TextShow CLLong 55 | -- | /Since: 2/ 56 | deriving instance TextShow CULLong 57 | -- | /Since: 2/ 58 | deriving instance TextShow CIntPtr 59 | -- | /Since: 2/ 60 | deriving instance TextShow CUIntPtr 61 | -- | /Since: 2/ 62 | deriving instance TextShow CIntMax 63 | -- | /Since: 2/ 64 | deriving instance TextShow CUIntMax 65 | -- | /Since: 2/ 66 | deriving instance TextShow CClock 67 | -- | /Since: 2/ 68 | deriving instance TextShow CTime 69 | -- | /Since: 2/ 70 | deriving instance TextShow CUSeconds 71 | -- | /Since: 2/ 72 | deriving instance TextShow CSUSeconds 73 | -- | /Since: 2/ 74 | deriving instance TextShow CFloat 75 | -- | /Since: 2/ 76 | deriving instance TextShow CDouble 77 | 78 | #if MIN_VERSION_base(4,10,0) 79 | -- | Only available with @base-4.10.0.0@ or later. 80 | -- 81 | -- /Since: 3.6/ 82 | deriving instance TextShow CBool 83 | #endif 84 | -------------------------------------------------------------------------------- /src/TextShow/GHC/RTS/Flags.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE CPP #-} 2 | {-# LANGUAGE TemplateHaskell #-} 3 | {-# OPTIONS_GHC -Wno-orphans #-} 4 | {-| 5 | Module: TextShow.GHC.RTS.Flags 6 | Copyright: (C) 2014-2017 Ryan Scott 7 | License: BSD-style (see the file LICENSE) 8 | Maintainer: Ryan Scott 9 | Stability: Provisional 10 | Portability: GHC 11 | 12 | 'TextShow' instances for data types in the 'GHC.RTS.Flags' module. 13 | 14 | /Since: 2/ 15 | -} 16 | module TextShow.GHC.RTS.Flags () where 17 | 18 | import GHC.RTS.Flags 19 | #if MIN_VERSION_base(4,21,0) 20 | import qualified GHC.IO.SubSystem as SubSystem 21 | #elif MIN_VERSION_base(4,15,0) 22 | import qualified GHC.RTS.Flags as SubSystem 23 | #endif 24 | 25 | import TextShow.Data.Bool () 26 | import TextShow.Data.Char () 27 | import TextShow.Data.Floating () 28 | import TextShow.Data.Integral () 29 | import TextShow.Data.List () 30 | import TextShow.Data.Maybe () 31 | import TextShow.TH.Internal (deriveTextShow) 32 | import TextShow.TH.Names (giveGCStatsTypeName, doCostCentresTypeName, 33 | doHeapProfileTypeName, doTraceTypeName) 34 | 35 | -- | /Since: 2.1/ 36 | $(deriveTextShow giveGCStatsTypeName) 37 | -- | /Since: 2.1/ 38 | $(deriveTextShow doCostCentresTypeName) 39 | -- | /Since: 2.1/ 40 | $(deriveTextShow doHeapProfileTypeName) 41 | -- | /Since: 2.1/ 42 | $(deriveTextShow doTraceTypeName) 43 | 44 | -- | /Since: 2/ 45 | $(deriveTextShow ''GCFlags) 46 | -- | /Since: 2/ 47 | $(deriveTextShow ''ConcFlags) 48 | #if MIN_VERSION_base(4,15,0) 49 | -- | /Since: 3.9/ 50 | $(deriveTextShow ''SubSystem.IoSubSystem) 51 | #endif 52 | #if MIN_VERSION_base(4,21,0) 53 | -- | /Since: 3.11/ 54 | $(deriveTextShow ''IoManagerFlag) 55 | #endif 56 | -- | /Since: 2/ 57 | $(deriveTextShow ''MiscFlags) 58 | -- | /Since: 2/ 59 | $(deriveTextShow ''DebugFlags) 60 | -- | /Since: 2/ 61 | $(deriveTextShow ''CCFlags) 62 | -- | /Since: 2/ 63 | $(deriveTextShow ''ProfFlags) 64 | -- | /Since: 2/ 65 | $(deriveTextShow ''TraceFlags) 66 | -- | /Since: 2/ 67 | $(deriveTextShow ''TickyFlags) 68 | #if MIN_VERSION_base(4,10,0) 69 | -- | Only available with @base-4.10.0.0@ or later. 70 | -- 71 | -- /Since: 3.3/ 72 | $(deriveTextShow ''ParFlags) 73 | #endif 74 | #if MIN_VERSION_base(4,20,0) 75 | -- | Only available with @base-4.20.0.0@ or later. 76 | -- 77 | -- /Since: 3.10.5/ 78 | $(deriveTextShow ''HpcFlags) 79 | #endif 80 | -- | /Since: 2/ 81 | $(deriveTextShow ''RTSFlags) 82 | -------------------------------------------------------------------------------- /tests/Derived/TypeSynonyms.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE DeriveGeneric #-} 2 | {-# LANGUAGE GeneralizedNewtypeDeriving #-} 3 | {-# LANGUAGE TemplateHaskell #-} 4 | {-# LANGUAGE TypeFamilies #-} 5 | {-# OPTIONS_GHC -Wno-orphans #-} 6 | 7 | {-| 8 | Module: Derived.TypeSynonyms 9 | Copyright: (C) 2014-2017 Ryan Scott 10 | License: BSD-style (see the file LICENSE) 11 | Maintainer: Ryan Scott 12 | Stability: Provisional 13 | Portability: GHC 14 | 15 | Defines data types that use type synonyms. 16 | -} 17 | module Derived.TypeSynonyms (TyCon(..), TyFamily(..)) where 18 | 19 | import Control.Monad.Trans.Instances () 20 | 21 | import Data.Orphans () 22 | 23 | import GHC.Generics (Generic, Generic1) 24 | 25 | import Prelude 26 | 27 | import Test.QuickCheck (Arbitrary) 28 | 29 | import Text.Show.Deriving (deriveShow1, deriveShow2) 30 | 31 | import TextShow.TH (deriveTextShow, deriveTextShow1, deriveTextShow2) 32 | 33 | ------------------------------------------------------------------------------- 34 | 35 | type FakeOut a = Int 36 | type Id a = a 37 | type Flip f a b = f b a 38 | 39 | ------------------------------------------------------------------------------- 40 | 41 | newtype TyCon a b = TyCon 42 | ( Id (FakeOut (Id a)) 43 | , Id (FakeOut (Id b)) 44 | , Id (Flip Either (Id a) (Id Int)) 45 | , Id (Flip Either (Id b) (Id a)) 46 | ) 47 | deriving ( Arbitrary 48 | , Show 49 | , Generic 50 | , Generic1 51 | ) 52 | 53 | ------------------------------------------------------------------------------- 54 | 55 | data family TyFamily y z :: * 56 | 57 | newtype instance TyFamily a b = TyFamily 58 | ( Id (FakeOut (Id a)) 59 | , Id (FakeOut (Id b)) 60 | , Id (Flip Either (Id a) (Id Int)) 61 | , Id (Flip Either (Id b) (Id a)) 62 | ) 63 | deriving ( Arbitrary 64 | , Show 65 | , Generic 66 | , Generic1 67 | ) 68 | 69 | ------------------------------------------------------------------------------- 70 | 71 | $(deriveShow1 ''TyCon) 72 | $(deriveShow2 ''TyCon) 73 | 74 | $(deriveTextShow ''TyCon) 75 | $(deriveTextShow1 ''TyCon) 76 | $(deriveTextShow2 ''TyCon) 77 | 78 | $(deriveShow1 'TyFamily) 79 | $(deriveShow2 'TyFamily) 80 | 81 | $(deriveTextShow 'TyFamily) 82 | $(deriveTextShow1 'TyFamily) 83 | $(deriveTextShow2 'TyFamily) 84 | -------------------------------------------------------------------------------- /tests/Spec/Data/MonoidSpec.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE CPP #-} 2 | 3 | {-| 4 | Module: Spec.Data.MonoidSpec 5 | Copyright: (C) 2014-2017 Ryan Scott 6 | License: BSD-style (see the file LICENSE) 7 | Maintainer: Ryan Scott 8 | Stability: Provisional 9 | Portability: GHC 10 | 11 | @hspec@ tests for data types in the "Data.Monoid" module. 12 | -} 13 | module Spec.Data.MonoidSpec (main, spec) where 14 | 15 | import Data.Monoid 16 | import Data.Proxy (Proxy(..)) 17 | 18 | import Instances.Data.Monoid () 19 | 20 | import Spec.Utils (matchesTextShowSpec, genericTextShowSpec, genericTextShow1Spec) 21 | 22 | import Test.Hspec (Spec, describe, hspec, parallel) 23 | 24 | main :: IO () 25 | main = hspec spec 26 | 27 | spec :: Spec 28 | spec = parallel $ do 29 | describe "All" $ do 30 | let p :: Proxy All 31 | p = Proxy 32 | matchesTextShowSpec p 33 | genericTextShowSpec p 34 | describe "Any" $ do 35 | let p :: Proxy Any 36 | p = Proxy 37 | matchesTextShowSpec p 38 | genericTextShowSpec p 39 | describe "Dual Int" $ do 40 | let p :: Proxy (Dual Int) 41 | p = Proxy 42 | matchesTextShowSpec p 43 | genericTextShowSpec p 44 | genericTextShow1Spec p 45 | describe "First Int" $ do 46 | let p :: Proxy (First Int) 47 | p = Proxy 48 | matchesTextShowSpec p 49 | genericTextShowSpec p 50 | genericTextShow1Spec p 51 | describe "Last Int" $ do 52 | let p :: Proxy (Last Int) 53 | p = Proxy 54 | matchesTextShowSpec p 55 | genericTextShowSpec p 56 | genericTextShow1Spec p 57 | describe "Product Int" $ do 58 | let p :: Proxy (Product Int) 59 | p = Proxy 60 | matchesTextShowSpec p 61 | genericTextShowSpec p 62 | genericTextShow1Spec p 63 | describe "Sum Int" $ do 64 | let p :: Proxy (Sum Int) 65 | p = Proxy 66 | matchesTextShowSpec p 67 | genericTextShowSpec p 68 | genericTextShow1Spec p 69 | describe "Alt Maybe Int" $ do 70 | let p :: Proxy (Alt Maybe Int) 71 | p = Proxy 72 | matchesTextShowSpec p 73 | genericTextShowSpec p 74 | genericTextShow1Spec p 75 | #if MIN_VERSION_base(4,12,0) 76 | describe "Ap Maybe Int" $ do 77 | let p :: Proxy (Ap Maybe Int) 78 | p = Proxy 79 | matchesTextShowSpec p 80 | genericTextShowSpec p 81 | genericTextShow1Spec p 82 | #endif 83 | -------------------------------------------------------------------------------- /src/TextShow.hs: -------------------------------------------------------------------------------- 1 | {-| 2 | Module: TextShow 3 | Copyright: (C) 2014-2017 Ryan Scott 4 | License: BSD-style (see the file LICENSE) 5 | Maintainer: Ryan Scott 6 | Stability: Provisional 7 | Portability: GHC 8 | 9 | Efficiently convert from values to 'Text' via 'Builder's. 10 | 11 | /Since: 2/ 12 | -} 13 | module TextShow ( 14 | -- * The @TextShow@ classes 15 | -- ** 'TextShow' 16 | TextShow(..) 17 | , showbParen 18 | , showtParen 19 | , showtlParen 20 | , showbCommaSpace 21 | , showtCommaSpace 22 | , showtlCommaSpace 23 | , showbSpace 24 | , showtSpace 25 | , showtlSpace 26 | -- ** 'TextShow1' 27 | , TextShow1(..) 28 | , showbPrec1 29 | , showbUnaryWith 30 | , liftShowtPrec 31 | , liftShowtlPrec 32 | -- ** 'TextShow2' 33 | , TextShow2(..) 34 | , showbPrec2 35 | , showbBinaryWith 36 | , liftShowtPrec2 37 | , liftShowtlPrec2 38 | -- * 'Builder's 39 | -- ** The 'Builder' type 40 | , Builder 41 | , toText 42 | , toLazyText 43 | , toLazyTextWith 44 | , toString 45 | -- ** Constructing 'Builder's 46 | , singleton 47 | , fromText 48 | , fromLazyText 49 | , fromString 50 | -- ** Flushing the buffer state 51 | , flush 52 | -- ** 'Builder' utility functions 53 | , lengthB 54 | , unlinesB 55 | , unwordsB 56 | -- * Printing values 57 | , printT 58 | , printTL 59 | , hPrintT 60 | , hPrintTL 61 | -- * Conversions 62 | -- ** Conversion between 'TextShow' and string 'Show' 63 | , FromStringShow(..) 64 | , FromTextShow(..) 65 | , FromStringShow1(..) 66 | , FromTextShow1(..) 67 | , FromStringShow2(..) 68 | , FromTextShow2(..) 69 | , showsPrecToShowbPrec 70 | , showsToShowb 71 | , showbPrecToShowsPrec 72 | , showbToShows 73 | -- ** Conversions between 'Builder', strict 'TS.Text', and lazy 'TL.Text' 74 | , showtPrecToShowbPrec 75 | , showtlPrecToShowbPrec 76 | , showtToShowb 77 | , showtlToShowb 78 | , showbPrecToShowtPrec 79 | , showbPrecToShowtlPrec 80 | , showbToShowt 81 | , showbToShowtl 82 | ) where 83 | 84 | import qualified Data.Text as TS () 85 | import qualified Data.Text.Lazy as TL () 86 | import Data.Text.Lazy.Builder 87 | 88 | import Prelude () 89 | 90 | import TextShow.Classes 91 | import TextShow.FromStringTextShow 92 | import TextShow.Instances () 93 | import TextShow.Utils (toString, toText, lengthB, unlinesB, unwordsB) 94 | -------------------------------------------------------------------------------- /tests/Spec/System/IOSpec.hs: -------------------------------------------------------------------------------- 1 | {-| 2 | Module: Spec.System.IOSpec 3 | Copyright: (C) 2014-2017 Ryan Scott 4 | License: BSD-style (see the file LICENSE) 5 | Maintainer: Ryan Scott 6 | Stability: Provisional 7 | Portability: GHC 8 | 9 | @hspec@ tests for data types in the "System.IO" module. 10 | -} 11 | module Spec.System.IOSpec (main, spec) where 12 | 13 | import Data.Proxy (Proxy(..)) 14 | 15 | import GHC.IO.Encoding.Failure (CodingFailureMode) 16 | import GHC.IO.Encoding.Types (CodingProgress) 17 | 18 | import Instances.System.IO () 19 | 20 | import Prelude () 21 | import Prelude.Compat 22 | 23 | import Spec.Utils (matchesTextShowSpec, prop_matchesTextShow) 24 | 25 | import System.IO (BufferMode, IOMode, HandlePosn, Newline, 26 | NewlineMode, SeekMode, Handle, mkTextEncoding) 27 | 28 | import Test.Hspec (Spec, describe, hspec, parallel) 29 | import Test.Hspec.QuickCheck (prop) 30 | import Test.QuickCheck (Property, generate, ioProperty, oneof) 31 | 32 | main :: IO () 33 | main = hspec spec 34 | 35 | spec :: Spec 36 | spec = parallel $ do 37 | describe "Handle" $ 38 | matchesTextShowSpec (Proxy :: Proxy Handle) 39 | describe "IOMode" $ 40 | matchesTextShowSpec (Proxy :: Proxy IOMode) 41 | describe "BufferMode" $ 42 | matchesTextShowSpec (Proxy :: Proxy BufferMode) 43 | describe "HandlePosn" $ 44 | matchesTextShowSpec (Proxy :: Proxy HandlePosn) 45 | describe "SeekMode" $ 46 | matchesTextShowSpec (Proxy :: Proxy SeekMode) 47 | describe "TextEncoding" $ 48 | prop "TextShow instance" prop_showTextEncoding 49 | describe "CodingProgress" $ 50 | matchesTextShowSpec (Proxy :: Proxy CodingProgress) 51 | describe "CodingFailureMode" $ 52 | matchesTextShowSpec (Proxy :: Proxy CodingFailureMode) 53 | describe "Newline" $ 54 | matchesTextShowSpec (Proxy :: Proxy Newline) 55 | describe "NewlineMode" $ 56 | matchesTextShowSpec (Proxy :: Proxy NewlineMode) 57 | 58 | -- | Verifies the 'TextShow' instance for 'TextEncoding' is accurate. 59 | prop_showTextEncoding :: Int -> Property 60 | prop_showTextEncoding p = ioProperty $ do 61 | -- Based on this description: 62 | -- http://hackage.haskell.org/package/base-4.7.0.2/docs/System-IO.html#v:mkTextEncoding 63 | utf <- generate . oneof $ map pure [ "UTF-8" 64 | , "UTF-16", "UTF-16BE", "UTF-16LE" 65 | , "UTF-32", "UTF-32BE", "UTF-32LE" 66 | ] 67 | tenc <- mkTextEncoding utf 68 | pure $ prop_matchesTextShow p tenc 69 | -------------------------------------------------------------------------------- /tests/Spec/Data/TypeableSpec.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE CPP #-} 2 | {-# LANGUAGE DataKinds #-} 3 | 4 | {-| 5 | Module: Spec.Data.TypeableSpec 6 | Copyright: (C) 2014-2017 Ryan Scott 7 | License: BSD-style (see the file LICENSE) 8 | Maintainer: Ryan Scott 9 | Stability: Provisional 10 | Portability: GHC 11 | 12 | @hspec@ tests for data types in the "Data.Typeable" module. 13 | -} 14 | module Spec.Data.TypeableSpec (main, spec) where 15 | 16 | import Data.Proxy (Proxy(..)) 17 | import Data.Typeable (TyCon) 18 | 19 | import GHC.Types (TrName, Module) 20 | 21 | #if MIN_VERSION_base(4,10,0) 22 | import Data.Kind (Type) 23 | import Type.Reflection (SomeTypeRep, TypeRep) 24 | #else 25 | import Data.Typeable (TypeRep) 26 | #endif 27 | 28 | import Instances.Data.Typeable () 29 | 30 | import Spec.Utils (matchesTextShowSpec) 31 | 32 | import Test.Hspec (Spec, describe, hspec, parallel) 33 | 34 | main :: IO () 35 | main = hspec spec 36 | 37 | spec :: Spec 38 | spec = parallel $ do 39 | describe "TyCon" $ 40 | matchesTextShowSpec (Proxy :: Proxy TyCon) 41 | describe "TrName" $ 42 | matchesTextShowSpec (Proxy :: Proxy TrName) 43 | describe "Module" $ 44 | matchesTextShowSpec (Proxy :: Proxy Module) 45 | #if MIN_VERSION_base(4,10,0) 46 | describe "SomeTypeRep" $ 47 | matchesTextShowSpec (Proxy :: Proxy SomeTypeRep) 48 | describe "TypeRep" $ do 49 | describe "TypeRep Type" $ 50 | matchesTextShowSpec (Proxy :: Proxy (TypeRep Type)) 51 | describe "TypeRep []" $ 52 | matchesTextShowSpec (Proxy :: Proxy (TypeRep [])) 53 | describe "TypeRep [Int]" $ 54 | matchesTextShowSpec (Proxy :: Proxy (TypeRep [Int])) 55 | describe "TypeRep '[Int]" $ 56 | matchesTextShowSpec (Proxy :: Proxy (TypeRep '[Int])) 57 | describe "TypeRep (Int, Int)" $ 58 | matchesTextShowSpec (Proxy :: Proxy (TypeRep (Int, Int))) 59 | describe "TypeRep '(Int, Int)" $ 60 | matchesTextShowSpec (Proxy :: Proxy (TypeRep '(Int, Int))) 61 | describe "TypeRep (Int -> Int)" $ 62 | matchesTextShowSpec (Proxy :: Proxy (TypeRep (Int -> Int))) 63 | describe "TypeRep ((,) Int)" $ 64 | matchesTextShowSpec (Proxy :: Proxy (TypeRep ((,) Int))) 65 | describe "TypeRep ('(,) Int)" $ 66 | matchesTextShowSpec (Proxy :: Proxy (TypeRep ('(,) Int))) 67 | describe "TypeRep (Either Int)" $ 68 | matchesTextShowSpec (Proxy :: Proxy (TypeRep (Either Int))) 69 | #else 70 | describe "TypeRep" $ 71 | matchesTextShowSpec (Proxy :: Proxy TypeRep) 72 | #endif 73 | -------------------------------------------------------------------------------- /src/TextShow/Foreign/Ptr.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE CPP #-} 2 | {-# LANGUAGE MagicHash #-} 3 | {-# OPTIONS_GHC -Wno-orphans #-} 4 | {-| 5 | Module: TextShow.Foreign.Ptr 6 | Copyright: (C) 2014-2017 Ryan Scott 7 | License: BSD-style (see the file LICENSE) 8 | Maintainer: Ryan Scott 9 | Stability: Provisional 10 | Portability: GHC 11 | 12 | 'TextShow' instances for pointer types used in the Haskell 13 | Foreign Function Interface (FFI). 14 | 15 | /Since: 2/ 16 | -} 17 | module TextShow.Foreign.Ptr () where 18 | 19 | import Data.Semigroup (mtimesDefault) 20 | import Data.Text.Lazy.Builder (Builder, singleton) 21 | 22 | import Foreign.ForeignPtr (ForeignPtr) 23 | import Foreign.Ptr (FunPtr, IntPtr, WordPtr, castFunPtrToPtr) 24 | 25 | import GHC.Exts (addr2Int#, int2Word#) 26 | import GHC.ForeignPtr (unsafeForeignPtrToPtr) 27 | import GHC.Num 28 | import GHC.Ptr (Ptr(..)) 29 | 30 | import Prelude () 31 | import Prelude.Compat 32 | 33 | import TextShow.Classes (TextShow(..), TextShow1(..)) 34 | import TextShow.Data.Integral (showbHex) 35 | import TextShow.Utils (lengthB) 36 | 37 | import Unsafe.Coerce (unsafeCoerce) 38 | 39 | #include "MachDeps.h" 40 | 41 | -- | /Since: 2/ 42 | instance TextShow (Ptr a) where 43 | showbPrec = liftShowbPrec undefined undefined 44 | {-# INLINE showbPrec #-} 45 | 46 | -- | /Since: 2/ 47 | instance TextShow1 Ptr where 48 | liftShowbPrec _ _ _ (Ptr a) = padOut . showbHex $ 49 | integerFromWord# (int2Word# (addr2Int# a)) 50 | where 51 | padOut :: Builder -> Builder 52 | padOut ls = 53 | singleton '0' <> singleton 'x' 54 | <> mtimesDefault (max 0 $ 2*SIZEOF_HSPTR - lengthB ls) (singleton '0') 55 | <> ls 56 | 57 | #if !(MIN_VERSION_base(4,15,0)) 58 | integerFromWord# = wordToInteger 59 | #endif 60 | 61 | -- | /Since: 2/ 62 | instance TextShow (FunPtr a) where 63 | showbPrec = liftShowbPrec undefined undefined 64 | {-# INLINE showbPrec #-} 65 | 66 | -- | /Since: 2/ 67 | instance TextShow1 FunPtr where 68 | liftShowbPrec _ _ _ = showb . castFunPtrToPtr 69 | {-# INLINE liftShowbPrec #-} 70 | 71 | -- | /Since: 2/ 72 | instance TextShow IntPtr where 73 | showbPrec p ip = showbPrec p (unsafeCoerce ip :: Integer) 74 | 75 | -- | /Since: 2/ 76 | instance TextShow WordPtr where 77 | showb wp = showb (unsafeCoerce wp :: Word) 78 | 79 | -- | /Since: 2/ 80 | instance TextShow (ForeignPtr a) where 81 | showbPrec = liftShowbPrec undefined undefined 82 | {-# INLINE showbPrec #-} 83 | 84 | -- | /Since: 2/ 85 | instance TextShow1 ForeignPtr where 86 | liftShowbPrec _ _ _ = showb . unsafeForeignPtrToPtr 87 | {-# INLINE liftShowbPrec #-} 88 | -------------------------------------------------------------------------------- /tests/Spec/Data/IntegralSpec.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE CPP #-} 2 | 3 | {-| 4 | Module: Spec.Data.IntegralSpec 5 | Copyright: (C) 2014-2017 Ryan Scott 6 | License: BSD-style (see the file LICENSE) 7 | Maintainer: Ryan Scott 8 | Stability: Provisional 9 | Portability: GHC 10 | 11 | @hspec@ tests for integral data types. 12 | -} 13 | module Spec.Data.IntegralSpec (main, spec) where 14 | 15 | import Data.Int (Int8, Int16, Int32, Int64) 16 | import Data.Proxy (Proxy(..)) 17 | import Data.Word (Word8, Word16, Word32, Word64) 18 | 19 | import Prelude () 20 | import Prelude.Compat 21 | 22 | import Spec.Utils (matchesTextShowSpec) 23 | 24 | import Test.Hspec (Spec, describe, hspec, parallel) 25 | 26 | #if !defined(mingw32_HOST_OS) 27 | import Data.Char (intToDigit) 28 | 29 | import Numeric (showIntAtBase) 30 | 31 | import Test.QuickCheck (Gen, arbitrary, getNonNegative, suchThat) 32 | import Test.Hspec (Expectation, shouldBe) 33 | import Test.Hspec.QuickCheck (prop) 34 | 35 | import TextShow (fromString) 36 | import TextShow.Data.Integral (showbIntAtBase) 37 | #endif 38 | 39 | main :: IO () 40 | main = hspec spec 41 | 42 | spec :: Spec 43 | spec = parallel $ do 44 | describe "Int" $ 45 | matchesTextShowSpec (Proxy :: Proxy Int) 46 | describe "Int8" $ 47 | matchesTextShowSpec (Proxy :: Proxy Int8) 48 | describe "Int16" $ 49 | matchesTextShowSpec (Proxy :: Proxy Int16) 50 | describe "Int32" $ 51 | matchesTextShowSpec (Proxy :: Proxy Int32) 52 | describe "Int64" $ 53 | matchesTextShowSpec (Proxy :: Proxy Int64) 54 | describe "Integer" $ 55 | matchesTextShowSpec (Proxy :: Proxy Integer) 56 | describe "Word" $ 57 | matchesTextShowSpec (Proxy :: Proxy Word) 58 | describe "Word8" $ 59 | matchesTextShowSpec (Proxy :: Proxy Word8) 60 | describe "Word16" $ 61 | matchesTextShowSpec (Proxy :: Proxy Word16) 62 | describe "Word32" $ 63 | matchesTextShowSpec (Proxy :: Proxy Word32) 64 | describe "Word64" $ 65 | matchesTextShowSpec (Proxy :: Proxy Word64) 66 | #if !defined(mingw32_HOST_OS) 67 | -- TODO: Figure out why this diverges on Windows 68 | describe "showbIntAtBase" $ 69 | prop "has the same output as showIntAtBase" prop_showIntAtBase 70 | #endif 71 | 72 | -- | Verifies 'showIntAtBase' and 'showbIntAtBase' generate the same output. 73 | #if !defined(mingw32_HOST_OS) 74 | prop_showIntAtBase :: Gen Expectation 75 | prop_showIntAtBase = do 76 | base <- arbitrary `suchThat` \b -> 1 < b && b <= 16 77 | i <- getNonNegative <$> arbitrary :: Gen Int 78 | pure $ fromString (showIntAtBase base intToDigit i "") `shouldBe` showbIntAtBase base intToDigit i 79 | #endif 80 | -------------------------------------------------------------------------------- /tests/Spec/Data/FloatingSpec.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE CPP #-} 2 | 3 | {-| 4 | Module: Spec.Data.FloatingSpec 5 | Copyright: (C) 2014-2017 Ryan Scott 6 | License: BSD-style (see the file LICENSE) 7 | Maintainer: Ryan Scott 8 | Stability: Provisional 9 | Portability: GHC 10 | 11 | @hspec@ tests for floating-point data types. 12 | -} 13 | module Spec.Data.FloatingSpec (main, spec) where 14 | 15 | import Data.Proxy (Proxy(..)) 16 | import Data.Text.Lazy.Builder.RealFloat (FPFormat) 17 | 18 | import Instances.Data.Floating () 19 | 20 | import Numeric (showEFloat, showFFloat, showGFloat, 21 | showFFloatAlt, showGFloatAlt) 22 | 23 | import Prelude () 24 | import Prelude.Compat 25 | 26 | import Spec.Utils (matchesTextShowSpec) 27 | 28 | import Test.Hspec (Spec, describe, hspec, parallel) 29 | import Test.Hspec.QuickCheck (prop) 30 | import Test.QuickCheck (Property, arbitrary, property, suchThat) 31 | 32 | import TextShow (Builder, fromString) 33 | import TextShow.Data.Floating (showbEFloat, showbFFloat, showbGFloat, 34 | showbFFloatAlt, showbGFloatAlt) 35 | 36 | main :: IO () 37 | main = hspec spec 38 | 39 | spec :: Spec 40 | spec = parallel $ do 41 | describe "Float" $ 42 | matchesTextShowSpec (Proxy :: Proxy Float) 43 | describe "Double" $ 44 | matchesTextShowSpec (Proxy :: Proxy Double) 45 | describe "showbEFloat" $ 46 | prop "has the same output as showEFloat" $ prop_showXFloat showEFloat showbEFloat 47 | describe "showbFFloat" $ 48 | prop "has the same output as showFFloat" $ prop_showXFloat showFFloat showbFFloat 49 | describe "showbGFloat" $ 50 | prop "has the same output as showGFloat" $ prop_showXFloat showGFloat showbGFloat 51 | describe "showbFFloatAlt" $ 52 | prop "has the same output as showFFloatAlt" $ prop_showXFloat showFFloatAlt showbFFloatAlt 53 | describe "showbGFloatAlt" $ 54 | prop "has the same output as showFFloatAlt" $ prop_showXFloat showGFloatAlt showbGFloatAlt 55 | describe "FPFormat" $ 56 | matchesTextShowSpec (Proxy :: Proxy FPFormat) 57 | 58 | -- | Verifies @showXFloat@ and @showbXFloat@ generate the same output (where @X@ 59 | -- is one of E, F, or G). 60 | prop_showXFloat :: (Maybe Int -> Double -> ShowS) 61 | -> (Maybe Int -> Double -> Builder) 62 | -> Double -> Property 63 | prop_showXFloat f1 f2 val = property $ do 64 | mb_digs <- arbitrary `suchThat` cond 65 | pure $ fromString (f1 mb_digs val "") == f2 mb_digs val 66 | where 67 | cond :: Maybe Int -> Bool 68 | cond mb_digs = 69 | mb_digs /= Nothing && mb_digs <= Just 10 70 | #if !(MIN_VERSION_base(4,12,0)) 71 | && mb_digs > Just 0 -- Work around Trac #15115 72 | #endif 73 | -------------------------------------------------------------------------------- /src/TextShow/Instances.hs: -------------------------------------------------------------------------------- 1 | {-| 2 | Module: TextShow.Instances 3 | Copyright: (C) 2014-2017 Ryan Scott 4 | License: BSD-style (see the file LICENSE) 5 | Maintainer: Ryan Scott 6 | Stability: Provisional 7 | Portability: GHC 8 | 9 | Imports all orphan 'TextShow', 'TextShow1', and 'TextShow2' instances covered 10 | by @text-show@ (except for the instances in `TextShow.Functions`, which are not 11 | imported by default). 12 | -} 13 | module TextShow.Instances () where 14 | 15 | import TextShow.Control.Applicative () 16 | import TextShow.Control.Concurrent () 17 | import TextShow.Control.Exception () 18 | import TextShow.Control.Monad.ST () 19 | 20 | import TextShow.Data.Array () 21 | import TextShow.Data.Array.Byte () 22 | import TextShow.Data.Bool () 23 | import TextShow.Data.ByteString () 24 | import TextShow.Data.Char () 25 | import TextShow.Data.Complex () 26 | import TextShow.Data.Data () 27 | import TextShow.Data.Dynamic () 28 | import TextShow.Data.Either () 29 | import TextShow.Data.Fixed () 30 | import TextShow.Data.Floating () 31 | import TextShow.Data.Functor.Compose () 32 | import TextShow.Data.Functor.Identity () 33 | import TextShow.Data.Functor.Product () 34 | import TextShow.Data.Functor.Sum () 35 | import TextShow.Data.Integral () 36 | import TextShow.Data.List () 37 | import TextShow.Data.List.NonEmpty () 38 | import TextShow.Data.Maybe () 39 | import TextShow.Data.Monoid () 40 | import TextShow.Data.Ord () 41 | import TextShow.Data.Proxy () 42 | import TextShow.Data.Ratio () 43 | import TextShow.Data.Semigroup () 44 | import TextShow.Data.Text () 45 | import TextShow.Data.Tuple () 46 | import TextShow.Data.Type.Coercion () 47 | import TextShow.Data.Type.Equality () 48 | import TextShow.Data.Typeable () 49 | import TextShow.Data.Version () 50 | import TextShow.Data.Void () 51 | 52 | import TextShow.Foreign.C.Types () 53 | import TextShow.Foreign.Ptr () 54 | 55 | import TextShow.GHC.Conc.Windows () 56 | import TextShow.GHC.Event () 57 | import TextShow.GHC.Fingerprint () 58 | import TextShow.GHC.Generics () 59 | import TextShow.GHC.RTS.Flags () 60 | import TextShow.GHC.Stack () 61 | import TextShow.GHC.StaticPtr () 62 | import TextShow.GHC.Stats () 63 | import TextShow.GHC.TypeLits () 64 | 65 | import TextShow.Numeric.Natural () 66 | 67 | import TextShow.System.Exit () 68 | import TextShow.System.IO () 69 | import TextShow.System.Posix.Types () 70 | 71 | import TextShow.Text.Read () 72 | -------------------------------------------------------------------------------- /src/TextShow/Data/Fixed.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE CPP #-} 2 | {-# OPTIONS_GHC -Wno-orphans #-} 3 | {-| 4 | Module: TextShow.Data.Fixed 5 | Copyright: (C) 2014-2017 Ryan Scott 6 | License: BSD-style (see the file LICENSE) 7 | Maintainer: Ryan Scott 8 | Stability: Provisional 9 | Portability: GHC 10 | 11 | Provides 'TextShow' instance for 'Fixed', as well as the 'showbFixed' function. 12 | 13 | /Since: 2/ 14 | -} 15 | module TextShow.Data.Fixed (showbFixed) where 16 | 17 | import Data.Fixed (Fixed(..), HasResolution(..)) 18 | import Data.Int (Int64) 19 | import Data.Semigroup (mtimesDefault) 20 | import Data.Text.Lazy.Builder (Builder, singleton) 21 | 22 | import Prelude () 23 | import Prelude.Compat 24 | 25 | import TextShow.Classes (TextShow(..)) 26 | import TextShow.Data.Integral () 27 | import TextShow.Utils (lengthB) 28 | 29 | #if MIN_VERSION_base(4,13,0) 30 | import TextShow.Classes (showbParen) 31 | #endif 32 | 33 | -- | Convert a 'Fixed' value to a 'Builder', where the first argument indicates 34 | -- whether to chop off trailing zeroes. 35 | -- 36 | -- /Since: 2/ 37 | showbFixed :: HasResolution a => Bool -> Fixed a -> Builder 38 | showbFixed chopTrailingZeroes fa@(MkFixed a) | a < 0 39 | = singleton '-' <> showbFixed chopTrailingZeroes (asTypeOf (MkFixed (negate a)) fa) 40 | showbFixed chopTrailingZeroes fa@(MkFixed a) 41 | = showb i <> withDotB (showbIntegerZeroes chopTrailingZeroes digits fracNum) 42 | where 43 | res = fromInteger $ resolution fa 44 | (i, d) = divMod (fromInteger a) res 45 | digits = ceiling (logBase 10 (fromInteger $ resolution fa) :: Double) 46 | maxnum = 10 ^ digits 47 | fracNum = divCeil (d * maxnum) res 48 | divCeil x y = (x + y - 1) `div` y 49 | 50 | -- | Only works for positive 'Integer's. 51 | showbIntegerZeroes :: Bool -> Int64 -> Integer -> Builder 52 | showbIntegerZeroes True _ 0 = mempty 53 | showbIntegerZeroes chopTrailingZeroes digits a 54 | = mtimesDefault (max 0 $ digits - lengthB sh) (singleton '0') <> sh' 55 | where 56 | sh, sh' :: Builder 57 | sh = showb a 58 | sh' = if chopTrailingZeroes then chopZeroesB a else sh 59 | 60 | -- | Chops off the trailing zeroes of an 'Integer'. 61 | chopZeroesB :: Integer -> Builder 62 | chopZeroesB 0 = mempty 63 | chopZeroesB a | mod a 10 == 0 = chopZeroesB (div a 10) 64 | chopZeroesB a = showb a 65 | 66 | -- | Prepends a dot to a non-empty 'Builder'. 67 | withDotB :: Builder -> Builder 68 | withDotB b | b == mempty = mempty 69 | | otherwise = singleton '.' <> b 70 | {-# INLINE withDotB #-} 71 | 72 | -- | /Since: 2/ 73 | instance HasResolution a => TextShow (Fixed a) where 74 | #if MIN_VERSION_base(4,13,0) 75 | showbPrec p n = showbParen (p > 6 && n < 0) $ showbFixed False n 76 | #else 77 | showb = showbFixed False 78 | {-# INLINE showb #-} 79 | #endif 80 | -------------------------------------------------------------------------------- /tests/Instances/System/Posix/Types.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE CPP #-} 2 | {-# LANGUAGE GeneralizedNewtypeDeriving #-} 3 | {-# LANGUAGE StandaloneDeriving #-} 4 | {-# OPTIONS_GHC -Wno-orphans #-} 5 | 6 | {-| 7 | Module: Instances.System.Posix.Types 8 | Copyright: (C) 2014-2017 Ryan Scott 9 | License: BSD-style (see the file LICENSE) 10 | Maintainer: Ryan Scott 11 | Stability: Provisional 12 | Portability: GHC 13 | 14 | 'Arbitrary' instances for data types in the "System.Posix.Types" module. 15 | -} 16 | module Instances.System.Posix.Types () where 17 | 18 | import Instances.Foreign.C.Types () 19 | import Instances.Foreign.Ptr () 20 | 21 | import System.Posix.Types 22 | 23 | import Test.QuickCheck (Arbitrary(..)) 24 | 25 | #include "HsBaseConfig.h" 26 | 27 | #if defined(HTYPE_DEV_T) 28 | deriving instance Arbitrary CDev 29 | #endif 30 | 31 | #if defined(HTYPE_INO_T) 32 | deriving instance Arbitrary CIno 33 | #endif 34 | 35 | #if defined(HTYPE_MODE_T) 36 | deriving instance Arbitrary CMode 37 | #endif 38 | 39 | #if defined(HTYPE_OFF_T) 40 | deriving instance Arbitrary COff 41 | #endif 42 | 43 | #if defined(HTYPE_PID_T) 44 | deriving instance Arbitrary CPid 45 | #endif 46 | 47 | #if defined(HTYPE_SSIZE_T) 48 | deriving instance Arbitrary CSsize 49 | #endif 50 | 51 | #if defined(HTYPE_GID_T) 52 | deriving instance Arbitrary CGid 53 | #endif 54 | 55 | #if defined(HTYPE_NLINK_T) 56 | deriving instance Arbitrary CNlink 57 | #endif 58 | 59 | #if defined(HTYPE_UID_T) 60 | deriving instance Arbitrary CUid 61 | #endif 62 | 63 | #if defined(HTYPE_CC_T) 64 | deriving instance Arbitrary CCc 65 | #endif 66 | 67 | #if defined(HTYPE_SPEED_T) 68 | deriving instance Arbitrary CSpeed 69 | #endif 70 | 71 | #if defined(HTYPE_TCFLAG_T) 72 | deriving instance Arbitrary CTcflag 73 | #endif 74 | 75 | #if defined(HTYPE_RLIM_T) 76 | deriving instance Arbitrary CRLim 77 | #endif 78 | 79 | #if MIN_VERSION_base(4,10,0) 80 | # if defined(HTYPE_BLKSIZE_T) 81 | deriving instance Arbitrary CBlkSize 82 | # endif 83 | 84 | # if defined(HTYPE_BLKCNT_T) 85 | deriving instance Arbitrary CBlkCnt 86 | # endif 87 | 88 | # if defined(HTYPE_CLOCKID_T) 89 | deriving instance Arbitrary CClockId 90 | # endif 91 | 92 | # if defined(HTYPE_FSBLKCNT_T) 93 | deriving instance Arbitrary CFsBlkCnt 94 | # endif 95 | 96 | # if defined(HTYPE_FSFILCNT_T) 97 | deriving instance Arbitrary CFsFilCnt 98 | # endif 99 | 100 | # if defined(HTYPE_ID_T) 101 | deriving instance Arbitrary CId 102 | # endif 103 | 104 | # if defined(HTYPE_KEY_T) 105 | deriving instance Arbitrary CKey 106 | # endif 107 | 108 | # if defined(HTYPE_TIMER_T) 109 | deriving instance Arbitrary CTimer 110 | # endif 111 | #endif 112 | 113 | deriving instance Arbitrary Fd 114 | -------------------------------------------------------------------------------- /tests/Instances/Data/Tuple.hs: -------------------------------------------------------------------------------- 1 | {-# OPTIONS_GHC -Wno-orphans #-} 2 | 3 | {-| 4 | Module: Instances.Data.Tuple 5 | Copyright: (C) 2014-2017 Ryan Scott 6 | License: BSD-style (see the file LICENSE) 7 | Maintainer: Ryan Scott 8 | Stability: Provisional 9 | Portability: GHC 10 | 11 | 'Arbitrary' instances for tuple types. 12 | -} 13 | module Instances.Data.Tuple () where 14 | 15 | import Generics.Deriving.Instances () 16 | import Instances.Utils.GenericArbitrary (genericArbitrary) 17 | import Test.QuickCheck (Arbitrary(..)) 18 | 19 | instance ( Arbitrary a 20 | , Arbitrary b 21 | , Arbitrary c 22 | , Arbitrary d 23 | , Arbitrary e 24 | , Arbitrary f 25 | , Arbitrary g 26 | , Arbitrary h 27 | , Arbitrary i 28 | , Arbitrary j 29 | , Arbitrary k 30 | ) => Arbitrary (a, b, c, d, e, f, g, h, i, j, k) where 31 | arbitrary = genericArbitrary 32 | 33 | instance ( Arbitrary a 34 | , Arbitrary b 35 | , Arbitrary c 36 | , Arbitrary d 37 | , Arbitrary e 38 | , Arbitrary f 39 | , Arbitrary g 40 | , Arbitrary h 41 | , Arbitrary i 42 | , Arbitrary j 43 | , Arbitrary k 44 | , Arbitrary l 45 | ) => Arbitrary (a, b, c, d, e, f, g, h, i, j, k, l) where 46 | arbitrary = genericArbitrary 47 | 48 | instance ( Arbitrary a 49 | , Arbitrary b 50 | , Arbitrary c 51 | , Arbitrary d 52 | , Arbitrary e 53 | , Arbitrary f 54 | , Arbitrary g 55 | , Arbitrary h 56 | , Arbitrary i 57 | , Arbitrary j 58 | , Arbitrary k 59 | , Arbitrary l 60 | , Arbitrary m 61 | ) => Arbitrary (a, b, c, d, e, f, g, h, i, j, k, l, m) where 62 | arbitrary = genericArbitrary 63 | 64 | instance ( Arbitrary a 65 | , Arbitrary b 66 | , Arbitrary c 67 | , Arbitrary d 68 | , Arbitrary e 69 | , Arbitrary f 70 | , Arbitrary g 71 | , Arbitrary h 72 | , Arbitrary i 73 | , Arbitrary j 74 | , Arbitrary k 75 | , Arbitrary l 76 | , Arbitrary m 77 | , Arbitrary n 78 | ) => Arbitrary (a, b, c, d, e, f, g, h, i, j, k, l, m, n) where 79 | arbitrary = genericArbitrary 80 | 81 | instance ( Arbitrary a 82 | , Arbitrary b 83 | , Arbitrary c 84 | , Arbitrary d 85 | , Arbitrary e 86 | , Arbitrary f 87 | , Arbitrary g 88 | , Arbitrary h 89 | , Arbitrary i 90 | , Arbitrary j 91 | , Arbitrary k 92 | , Arbitrary l 93 | , Arbitrary m 94 | , Arbitrary n 95 | , Arbitrary o 96 | ) => Arbitrary (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) where 97 | arbitrary = genericArbitrary 98 | -------------------------------------------------------------------------------- /src/TextShow/Data/Text.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE OverloadedStrings #-} 2 | {-# LANGUAGE TemplateHaskell #-} 3 | {-# OPTIONS_GHC -Wno-deprecations #-} -- TODO: Remove this later 4 | {-# OPTIONS_GHC -Wno-orphans #-} 5 | {-| 6 | Module: TextShow.Data.Text 7 | Copyright: (C) 2014-2017 Ryan Scott 8 | License: BSD-style (see the file LICENSE) 9 | Maintainer: Ryan Scott 10 | Stability: Provisional 11 | Portability: GHC 12 | 13 | Defines 'TextShow' instances for 'Text' types, as well as other miscellaneous 14 | data types from the @text@ package. 15 | 16 | Note that this module deliberately does not define a 'TextShow' instance for 17 | the @I16@ data type from @Data.Text.Foreign@, as that module is not available 18 | on certain widely used variants of GHC (e.g., @reflex-platform@). See #40 19 | for more details. If this is a problem for you, please file an issue. 20 | 21 | /Since: 2/ 22 | -} 23 | module TextShow.Data.Text () where 24 | 25 | import qualified Data.Text as TS 26 | import Data.Text.Encoding (Decoding(..)) 27 | import Data.Text.Encoding.Error (UnicodeException(..)) 28 | import Data.Text.Internal.Fusion.Size (Size) 29 | import qualified Data.Text.Lazy as TL 30 | import Data.Text.Lazy.Builder (Builder, fromString, singleton, 31 | toLazyText) 32 | 33 | import GHC.Show (appPrec) 34 | 35 | import Prelude () 36 | import Prelude.Compat 37 | 38 | import TextShow.Classes (TextShow(..), showbParen) 39 | import TextShow.Data.ByteString () 40 | import TextShow.Data.Char (showbString) 41 | import TextShow.Data.Integral (showbHex) 42 | import TextShow.TH.Internal (deriveTextShow) 43 | 44 | -- | /Since: 2/ 45 | instance TextShow TS.Text where 46 | showb = showbString . TS.unpack 47 | {-# INLINE showb #-} 48 | 49 | -- | /Since: 2/ 50 | instance TextShow TL.Text where 51 | showb = showbString . TL.unpack 52 | {-# INLINE showb #-} 53 | 54 | -- | /Since: 2/ 55 | instance TextShow Builder where 56 | showb = showb . toLazyText 57 | {-# INLINE showb #-} 58 | 59 | -- | /Since: 2/ 60 | instance TextShow UnicodeException where 61 | showb (DecodeError desc (Just w)) 62 | = "Cannot decode byte '\\x" <> showbHex w <> "': " <> fromString desc 63 | showb (DecodeError desc Nothing) 64 | = "Cannot decode input: " <> fromString desc 65 | showb (EncodeError desc (Just c)) 66 | = "Cannot encode character '\\x" <> showbHex (fromEnum c) <> "': " <> fromString desc 67 | showb (EncodeError desc Nothing) 68 | = "Cannot encode input: " <> fromString desc 69 | 70 | -- | /Since: 2/ 71 | instance TextShow Decoding where 72 | showbPrec p (Some t bs _) = showbParen (p > appPrec) $ 73 | "Some " <> showb t <> 74 | singleton ' ' <> showb bs <> 75 | " _" 76 | {-# INLINE showbPrec #-} 77 | 78 | -- | /Since: 2/ 79 | $(deriveTextShow ''Size) 80 | -------------------------------------------------------------------------------- /tests/Spec/Foreign/C/TypesSpec.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE CPP #-} 2 | 3 | {-| 4 | Module: Spec.Foreign.C.TypesSpec 5 | Copyright: (C) 2014-2017 Ryan Scott 6 | License: BSD-style (see the file LICENSE) 7 | Maintainer: Ryan Scott 8 | Stability: Provisional 9 | Portability: GHC 10 | 11 | @hspec@ tests for data types in the "Foreign.C.Types" module. 12 | -} 13 | module Spec.Foreign.C.TypesSpec (main, spec) where 14 | 15 | import Data.Proxy (Proxy(..)) 16 | import Foreign.C.Types 17 | import Instances.Foreign.C.Types () 18 | import Spec.Utils (matchesTextShowSpec) 19 | import Test.Hspec (Spec, describe, hspec, parallel) 20 | import Test.QuickCheck.Instances () 21 | 22 | main :: IO () 23 | main = hspec spec 24 | 25 | spec :: Spec 26 | spec = parallel $ do 27 | describe "CChar" $ 28 | matchesTextShowSpec (Proxy :: Proxy CChar) 29 | describe "CSChar" $ 30 | matchesTextShowSpec (Proxy :: Proxy CSChar) 31 | describe "CUChar" $ 32 | matchesTextShowSpec (Proxy :: Proxy CUChar) 33 | describe "CShort" $ 34 | matchesTextShowSpec (Proxy :: Proxy CShort) 35 | describe "CUShort" $ 36 | matchesTextShowSpec (Proxy :: Proxy CUShort) 37 | describe "CInt" $ 38 | matchesTextShowSpec (Proxy :: Proxy CInt) 39 | describe "CUInt" $ 40 | matchesTextShowSpec (Proxy :: Proxy CUInt) 41 | describe "CLong" $ 42 | matchesTextShowSpec (Proxy :: Proxy CLong) 43 | describe "CULong" $ 44 | matchesTextShowSpec (Proxy :: Proxy CULong) 45 | describe "CPtrdiff" $ 46 | matchesTextShowSpec (Proxy :: Proxy CPtrdiff) 47 | describe "CSize" $ 48 | matchesTextShowSpec (Proxy :: Proxy CSize) 49 | describe "CWchar" $ 50 | matchesTextShowSpec (Proxy :: Proxy CWchar) 51 | describe "CSigAtomic" $ 52 | matchesTextShowSpec (Proxy :: Proxy CSigAtomic) 53 | describe "CLLong" $ 54 | matchesTextShowSpec (Proxy :: Proxy CLLong) 55 | describe "CULLong" $ 56 | matchesTextShowSpec (Proxy :: Proxy CULLong) 57 | describe "CIntPtr" $ 58 | matchesTextShowSpec (Proxy :: Proxy CIntPtr) 59 | describe "CUIntPtr" $ 60 | matchesTextShowSpec (Proxy :: Proxy CUIntPtr) 61 | describe "CIntMax" $ 62 | matchesTextShowSpec (Proxy :: Proxy CIntMax) 63 | describe "CUIntMax" $ 64 | matchesTextShowSpec (Proxy :: Proxy CUIntMax) 65 | describe "CClock" $ 66 | matchesTextShowSpec (Proxy :: Proxy CClock) 67 | describe "CTime" $ 68 | matchesTextShowSpec (Proxy :: Proxy CTime) 69 | describe "CUSeconds" $ 70 | matchesTextShowSpec (Proxy :: Proxy CUSeconds) 71 | describe "CSUSeconds" $ 72 | matchesTextShowSpec (Proxy :: Proxy CSUSeconds) 73 | describe "CFloat" $ 74 | matchesTextShowSpec (Proxy :: Proxy CFloat) 75 | describe "CDouble" $ 76 | matchesTextShowSpec (Proxy :: Proxy CDouble) 77 | #if MIN_VERSION_base(4,10,0) 78 | describe "CBool" $ 79 | matchesTextShowSpec (Proxy :: Proxy CBool) 80 | #endif 81 | -------------------------------------------------------------------------------- /shared/TextShow/TH/Names.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE CPP #-} 2 | {-# LANGUAGE TemplateHaskellQuotes #-} 3 | 4 | {-| 5 | Module: TextShow.TH.Names 6 | Copyright: (C) 2014-2017 Ryan Scott 7 | License: BSD-style (see the file LICENSE) 8 | Maintainer: Ryan Scott 9 | Stability: Provisional 10 | Portability: GHC 11 | 12 | Template Haskell names to eliminate some boilerplate. 13 | -} 14 | module TextShow.TH.Names ( 15 | evtCloseValName, 16 | eventIsValName, 17 | fdKeyTypeName, 18 | uniqueTypeName, 19 | asInt64ValName, 20 | giveGCStatsTypeName, 21 | doCostCentresTypeName, 22 | doHeapProfileTypeName, 23 | doTraceTypeName, 24 | ) where 25 | 26 | import GHC.RTS.Flags (GiveGCStats, DoCostCentres, DoHeapProfile, DoTrace) 27 | import Language.Haskell.TH.Syntax 28 | 29 | ------------------------------------------------------------------------------- 30 | 31 | -- | Creates a 'Name' for a value from the "GHC.Event.Internal" module. 32 | mkEventName_v :: String -> Name 33 | #if MIN_VERSION_base(4,20,0) 34 | mkEventName_v = mkNameG_v "ghc-internal" "GHC.Internal.Event.Internal.Types" 35 | #elif MIN_VERSION_base(4,15,0) 36 | mkEventName_v = mkNameG_v "base" "GHC.Event.Internal.Types" 37 | #else 38 | mkEventName_v = mkNameG_v "base" "GHC.Event.Internal" 39 | #endif 40 | 41 | -- | The 'Name' of 'evtClose'. 42 | evtCloseValName :: Name 43 | evtCloseValName = mkEventName_v "evtClose" 44 | 45 | -- | The 'Name' of 'eventIs'. 46 | eventIsValName :: Name 47 | eventIsValName = mkEventName_v "eventIs" 48 | 49 | -- | The 'Name' of 'FdKey'. 50 | fdKeyTypeName :: Name 51 | #if MIN_VERSION_base(4,20,0) 52 | fdKeyTypeName = mkNameG_tc "ghc-internal" "GHC.Internal.Event.Manager" "FdKey" 53 | #else 54 | fdKeyTypeName = mkNameG_tc "base" "GHC.Event.Manager" "FdKey" 55 | #endif 56 | 57 | -- | The 'Name' of 'Unique'. 58 | uniqueTypeName :: Name 59 | #if MIN_VERSION_base(4,20,0) 60 | uniqueTypeName = mkNameG_tc "ghc-internal" "GHC.Internal.Event.Unique" "Unique" 61 | #else 62 | uniqueTypeName = mkNameG_tc "base" "GHC.Event.Unique" "Unique" 63 | #endif 64 | 65 | -- | The 'Name' of 'asInt64' (or, 'asInt' on @base-4.10.0.0@ or later). 66 | asInt64ValName :: Name 67 | #if MIN_VERSION_base(4,20,0) 68 | asInt64ValName = mkNameG_fld "ghc-internal" "GHC.Internal.Event.Unique" "Unique" "asInt" 69 | #elif MIN_VERSION_base(4,19,0) 70 | asInt64ValName = mkNameG_fld "base" "GHC.Event.Unique" "Unique" "asInt" 71 | #elif MIN_VERSION_base(4,10,0) 72 | asInt64ValName = mkNameG_v "base" "GHC.Event.Unique" "asInt" 73 | #else 74 | asInt64ValName = mkNameG_v "base" "GHC.Event.Unique" "asInt64" 75 | #endif 76 | 77 | -- | The 'Name' of 'GiveGCStats'. 78 | giveGCStatsTypeName :: Name 79 | giveGCStatsTypeName = ''GiveGCStats 80 | 81 | -- | The 'Name' of 'DoCostCentres'. 82 | doCostCentresTypeName :: Name 83 | doCostCentresTypeName = ''DoCostCentres 84 | 85 | -- | The 'Name' of 'DoHeapProfile'. 86 | doHeapProfileTypeName :: Name 87 | doHeapProfileTypeName = ''DoHeapProfile 88 | 89 | -- | The 'Name' of 'DoTrace'. 90 | doTraceTypeName :: Name 91 | doTraceTypeName = ''DoTrace 92 | -------------------------------------------------------------------------------- /tests/Derived/DatatypeContexts.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE DatatypeContexts #-} 2 | {-# LANGUAGE TemplateHaskell #-} 3 | {-# LANGUAGE TypeFamilies #-} 4 | -- I don't know how to silence the -XDatatypeContexts warnings otherwise... 5 | {-# OPTIONS_GHC -w #-} 6 | 7 | {-| 8 | Module: Derived.DatatypeContexts 9 | Copyright: (C) 2014-2017 Ryan Scott 10 | License: BSD-style (see the file LICENSE) 11 | Maintainer: Ryan Scott 12 | Stability: Provisional 13 | Portability: GHC 14 | 15 | Defines data types with DatatypeContexts (which are gross, but still possible). 16 | -} 17 | module Derived.DatatypeContexts (TyCon(..), TyFamily(..)) where 18 | 19 | import Data.Functor.Classes (Show1(..), Show2(..)) 20 | 21 | import Prelude () 22 | import Prelude.Compat 23 | 24 | import Test.QuickCheck (Arbitrary(..)) 25 | 26 | import Text.Show.Deriving (makeLiftShowsPrec, makeLiftShowsPrec2) 27 | 28 | import TextShow (TextShow(..), TextShow1(..), TextShow2(..)) 29 | import TextShow.TH (makeShowbPrec, makeLiftShowbPrec, makeLiftShowbPrec2) 30 | 31 | ------------------------------------------------------------------------------- 32 | 33 | data Ord a => TyCon a b c = TyCon a b c 34 | deriving Show 35 | 36 | ------------------------------------------------------------------------------- 37 | 38 | data family TyFamily x y z :: * 39 | 40 | data instance Ord a => TyFamily a b c = TyFamily a b c 41 | deriving Show 42 | 43 | ------------------------------------------------------------------------------- 44 | 45 | instance (Ord a, Arbitrary a, Arbitrary b, Arbitrary c) => Arbitrary (TyCon a b c) where 46 | arbitrary = TyCon <$> arbitrary <*> arbitrary <*> arbitrary 47 | 48 | instance (Ord a, Arbitrary a, Arbitrary b, Arbitrary c) => Arbitrary (TyFamily a b c) where 49 | arbitrary = TyFamily <$> arbitrary <*> arbitrary <*> arbitrary 50 | 51 | ------------------------------------------------------------------------------- 52 | 53 | $(return []) 54 | 55 | instance (Ord a, Show a, Show b) => Show1 (TyCon a b) where 56 | liftShowsPrec = $(makeLiftShowsPrec ''TyCon) 57 | instance (Ord a, Show a) => Show2 (TyCon a) where 58 | liftShowsPrec2 = $(makeLiftShowsPrec2 ''TyCon) 59 | 60 | instance (Ord a, TextShow a, TextShow b, TextShow c) => TextShow (TyCon a b c) where 61 | showbPrec = $(makeShowbPrec ''TyCon) 62 | instance (Ord a, TextShow a, TextShow b) => TextShow1 (TyCon a b) where 63 | liftShowbPrec = $(makeLiftShowbPrec ''TyCon) 64 | instance (Ord a, TextShow a) => TextShow2 (TyCon a) where 65 | liftShowbPrec2 = $(makeLiftShowbPrec2 ''TyCon) 66 | 67 | instance (Ord a, Show a, Show b) => Show1 (TyFamily a b) where 68 | liftShowsPrec = $(makeLiftShowsPrec 'TyFamily) 69 | 70 | instance (Ord a, Show a) => Show2 (TyFamily a) where 71 | liftShowsPrec2 = $(makeLiftShowsPrec2 'TyFamily) 72 | 73 | instance (Ord a, TextShow a, TextShow b, TextShow c) => TextShow (TyFamily a b c) where 74 | showbPrec = $(makeShowbPrec 'TyFamily) 75 | instance (Ord a, TextShow a, TextShow b) => TextShow1 (TyFamily a b) where 76 | liftShowbPrec = $(makeLiftShowbPrec 'TyFamily) 77 | instance (Ord a, TextShow a) => TextShow2 (TyFamily a) where 78 | liftShowbPrec2 = $(makeLiftShowbPrec2 'TyFamily) 79 | -------------------------------------------------------------------------------- /tests/Spec/Control/ExceptionSpec.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE CPP #-} 2 | 3 | {-| 4 | Module: Spec.Control.ExceptionSpec 5 | Copyright: (C) 2014-2017 Ryan Scott 6 | License: BSD-style (see the file LICENSE) 7 | Maintainer: Ryan Scott 8 | Stability: Provisional 9 | Portability: GHC 10 | 11 | @hspec@ tests for data types in the "Control.Exception" module. 12 | -} 13 | module Spec.Control.ExceptionSpec (main, spec) where 14 | 15 | import Control.Exception 16 | #if MIN_VERSION_base(4,11,0) 17 | import Control.Exception.Base (FixIOException) 18 | #endif 19 | import Data.Proxy (Proxy(..)) 20 | import Instances.Control.Exception () 21 | import Spec.Utils (matchesTextShowSpec) 22 | import Test.Hspec (Spec, describe, hspec, parallel) 23 | 24 | main :: IO () 25 | main = hspec spec 26 | 27 | spec :: Spec 28 | spec = parallel . describe "TextShow.Control.Exception" $ do 29 | describe "SomeException" $ 30 | matchesTextShowSpec (Proxy :: Proxy SomeException) 31 | describe "IOException" $ 32 | matchesTextShowSpec (Proxy :: Proxy IOException) 33 | describe "ArithException" $ 34 | matchesTextShowSpec (Proxy :: Proxy ArithException) 35 | describe "ArrayException" $ 36 | matchesTextShowSpec (Proxy :: Proxy ArrayException) 37 | describe "AssertionFailed" $ 38 | matchesTextShowSpec (Proxy :: Proxy AssertionFailed) 39 | describe "SomeAsyncException" $ 40 | matchesTextShowSpec (Proxy :: Proxy SomeAsyncException) 41 | describe "AsyncException" $ 42 | matchesTextShowSpec (Proxy :: Proxy AsyncException) 43 | describe "NonTermination" $ 44 | matchesTextShowSpec (Proxy :: Proxy NonTermination) 45 | describe "NestedAtomically" $ 46 | matchesTextShowSpec (Proxy :: Proxy NestedAtomically) 47 | describe "BlockedIndefinitelyOnMVar" $ 48 | matchesTextShowSpec (Proxy :: Proxy BlockedIndefinitelyOnMVar) 49 | describe "BlockedIndefinitelyOnSTM" $ 50 | matchesTextShowSpec (Proxy :: Proxy BlockedIndefinitelyOnSTM) 51 | describe "AllocationLimitExceeded" $ 52 | matchesTextShowSpec (Proxy :: Proxy AllocationLimitExceeded) 53 | describe "TypeError" $ 54 | matchesTextShowSpec (Proxy :: Proxy TypeError) 55 | #if MIN_VERSION_base(4,10,0) 56 | describe "CompactionFailed" $ 57 | matchesTextShowSpec (Proxy :: Proxy CompactionFailed) 58 | #endif 59 | #if MIN_VERSION_base(4,11,0) 60 | describe "FixIOException" $ 61 | matchesTextShowSpec (Proxy :: Proxy FixIOException) 62 | #endif 63 | describe "Deadlock" $ 64 | matchesTextShowSpec (Proxy :: Proxy Deadlock) 65 | describe "NoMethodError" $ 66 | matchesTextShowSpec (Proxy :: Proxy NoMethodError) 67 | describe "PatternMatchFail" $ 68 | matchesTextShowSpec (Proxy :: Proxy PatternMatchFail) 69 | describe "RecConError" $ 70 | matchesTextShowSpec (Proxy :: Proxy RecConError) 71 | describe "RecSelError" $ 72 | matchesTextShowSpec (Proxy :: Proxy RecSelError) 73 | describe "RecUpdError" $ 74 | matchesTextShowSpec (Proxy :: Proxy RecUpdError) 75 | describe "ErrorCall" $ 76 | matchesTextShowSpec (Proxy :: Proxy ErrorCall) 77 | describe "MaskingState" $ 78 | matchesTextShowSpec (Proxy :: Proxy MaskingState) 79 | -------------------------------------------------------------------------------- /src/TextShow/Utils.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE CPP #-} 2 | {-# LANGUAGE MagicHash #-} 3 | 4 | {-| 5 | Module: TextShow.Utils 6 | Copyright: (C) 2014-2017 Ryan Scott 7 | License: BSD-style (see the file LICENSE) 8 | Maintainer: Ryan Scott 9 | Stability: Provisional 10 | Portability: GHC 11 | 12 | Miscellaneous utility functions. 13 | -} 14 | module TextShow.Utils ( 15 | i2d 16 | , isInfixDataCon 17 | , isSymVar 18 | , isTupleString 19 | , lengthB 20 | , toString 21 | , toText 22 | , unlinesB 23 | , unwordsB 24 | ) where 25 | 26 | import Data.Int (Int64) 27 | import Data.Text (Text) 28 | import Data.Text.Lazy (length, toStrict, unpack) 29 | import Data.Text.Lazy.Builder (Builder, singleton, toLazyText) 30 | 31 | import GHC.Exts (Char(C#), Int(I#), (+#), chr#, ord#) 32 | 33 | import Prelude () 34 | import Prelude.Compat hiding (length) 35 | 36 | #if defined(MIN_VERSION_ghc_boot_th) 37 | import GHC.Lexeme (startsVarSym) 38 | #else 39 | import Data.Char (isSymbol, ord) 40 | #endif 41 | 42 | -- | Unsafe conversion for decimal digits. 43 | i2d :: Int -> Char 44 | i2d (I# i#) = C# (chr# (ord# '0'# +# i#)) 45 | {-# INLINE i2d #-} 46 | 47 | -- | Checks if a 'String' names a valid Haskell infix data constructor (i.e., does 48 | -- it begin with a colon?). 49 | isInfixDataCon :: String -> Bool 50 | isInfixDataCon (':':_) = True 51 | isInfixDataCon _ = False 52 | {-# INLINE isInfixDataCon #-} 53 | 54 | -- | Checks if a 'String' names a valid Haskell infix, non-constructor function. 55 | isSymVar :: String -> Bool 56 | isSymVar "" = False 57 | isSymVar (c : _) = startsVarSym c 58 | 59 | #if !defined(MIN_VERSION_ghc_boot_th) 60 | startsVarSym :: Char -> Bool 61 | startsVarSym c = startsVarSymASCII c || (ord c > 0x7f && isSymbol c) -- Infix Ids 62 | 63 | startsVarSymASCII :: Char -> Bool 64 | startsVarSymASCII c = c `elem` "!#$%&*+./<=>?@\\^|~-" 65 | #endif 66 | 67 | -- | Checks if a 'String' represents a tuple (other than '()') 68 | isTupleString :: String -> Bool 69 | isTupleString ('(':',':_) = True 70 | isTupleString _ = False 71 | {-# INLINE isTupleString #-} 72 | 73 | -- | Computes the length of a 'Builder'. 74 | -- 75 | -- /Since: 2/ 76 | lengthB :: Builder -> Int64 77 | lengthB = length . toLazyText 78 | {-# INLINE lengthB #-} 79 | 80 | -- | Convert a 'Builder' to a 'String' (without surrounding it with double quotes, 81 | -- as 'show' would). 82 | -- 83 | -- /Since: 2/ 84 | toString :: Builder -> String 85 | toString = unpack . toLazyText 86 | {-# INLINE toString #-} 87 | 88 | -- | Convert a 'Builder' to a strict 'Text'. 89 | -- 90 | -- /Since: 2/ 91 | toText :: Builder -> Text 92 | toText = toStrict . toLazyText 93 | {-# INLINE toText #-} 94 | 95 | -- | Merges several 'Builder's, separating them by newlines. 96 | -- 97 | -- /Since: 2/ 98 | unlinesB :: [Builder] -> Builder 99 | unlinesB (b:bs) = b <> singleton '\n' <> unlinesB bs 100 | unlinesB [] = mempty 101 | 102 | -- | Merges several 'Builder's, separating them by spaces. 103 | -- 104 | -- /Since: 2/ 105 | unwordsB :: [Builder] -> Builder 106 | unwordsB (b:bs@(_:_)) = b <> singleton ' ' <> unwordsB bs 107 | unwordsB [b] = b 108 | unwordsB [] = mempty 109 | -------------------------------------------------------------------------------- /tests/Derived/RankNTypes.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE FlexibleInstances #-} 2 | {-# LANGUAGE OverloadedStrings #-} 3 | {-# LANGUAGE RankNTypes #-} 4 | {-# LANGUAGE StandaloneDeriving #-} 5 | {-# LANGUAGE TemplateHaskell #-} 6 | {-# LANGUAGE TypeFamilies #-} 7 | {-# OPTIONS_GHC -Wno-orphans #-} 8 | {-# OPTIONS_GHC -Wno-name-shadowing #-} 9 | 10 | {-| 11 | Module: Derived.RankNTypes 12 | Copyright: (C) 2014-2017 Ryan Scott 13 | License: BSD-style (see the file LICENSE) 14 | Maintainer: Ryan Scott 15 | Stability: Provisional 16 | Portability: GHC 17 | 18 | Defines data types with rank-n voodoo. 19 | -} 20 | module Derived.RankNTypes (TyCon(..), TyFamily(..)) where 21 | 22 | import Data.Functor.Classes (Show1(..), Show2(..)) 23 | 24 | import Prelude () 25 | import Prelude.Compat 26 | 27 | import Test.QuickCheck (Arbitrary(..)) 28 | 29 | import Text.Show.Deriving (deriveShow1, deriveShow2, 30 | makeLiftShowsPrec, makeLiftShowsPrec2) 31 | import TextShow (TextShow(..), TextShow1(..), TextShow2(..)) 32 | import TextShow.TH (deriveTextShow, deriveTextShow1, deriveTextShow2, 33 | makeShowbPrec, makeLiftShowbPrec, makeLiftShowbPrec2) 34 | 35 | ------------------------------------------------------------------------------- 36 | 37 | data TyCon a b = TyCon (forall a. Tagged2 a Int b) 38 | (forall b. Tagged2 b a a) 39 | 40 | deriving instance (Show a, Show b) => Show (TyCon a b) 41 | 42 | ------------------------------------------------------------------------------- 43 | 44 | data family TyFamily x y :: * 45 | 46 | data instance TyFamily a b = TyFamily (forall a. Tagged2 a Int b) 47 | (forall b. Tagged2 b a a) 48 | 49 | deriving instance (Show a, Show b) => Show (TyFamily a b) 50 | 51 | ------------------------------------------------------------------------------- 52 | 53 | newtype Tagged2 s t c = Tagged2 c 54 | deriving Show 55 | 56 | ------------------------------------------------------------------------------- 57 | 58 | instance (Arbitrary a, Arbitrary b) => Arbitrary (TyCon a b) where 59 | arbitrary = (\i1 i2 -> TyCon (Tagged2 i1) (Tagged2 i2)) 60 | <$> arbitrary <*> arbitrary 61 | 62 | instance (Arbitrary a, Arbitrary b) => Arbitrary (TyFamily a b) where 63 | arbitrary = (\i1 i2 -> TyFamily (Tagged2 i1) (Tagged2 i2)) 64 | <$> arbitrary <*> arbitrary 65 | 66 | ------------------------------------------------------------------------------- 67 | 68 | $(return []) 69 | 70 | instance TextShow c => TextShow (Tagged2 s t c) where 71 | showbPrec = $(makeShowbPrec ''Tagged2) 72 | 73 | instance TextShow1 (Tagged2 s t) where 74 | liftShowbPrec = $(makeLiftShowbPrec ''Tagged2) 75 | 76 | instance TextShow2 (Tagged2 s) where 77 | liftShowbPrec2 = $(makeLiftShowbPrec2 ''Tagged2) 78 | 79 | ------------------------------------------------------------------------------- 80 | 81 | instance Show1 (Tagged2 s t) where 82 | liftShowsPrec = $(makeLiftShowsPrec ''Tagged2) 83 | instance Show2 (Tagged2 s) where 84 | liftShowsPrec2 = $(makeLiftShowsPrec2 ''Tagged2) 85 | 86 | $(deriveShow1 ''TyCon) 87 | $(deriveShow2 ''TyCon) 88 | 89 | $(deriveTextShow ''TyCon) 90 | $(deriveTextShow1 ''TyCon) 91 | $(deriveTextShow2 ''TyCon) 92 | 93 | $(deriveShow1 'TyFamily) 94 | $(deriveShow2 'TyFamily) 95 | 96 | $(deriveTextShow 'TyFamily) 97 | $(deriveTextShow1 'TyFamily) 98 | $(deriveTextShow2 'TyFamily) 99 | --------------------------------------------------------------------------------