content: {-# LANGUAGE CPP #-}
  {-# LANGUAGE DataKinds #-}
  {-# LANGUAGE DeriveFunctor #-}
  {-# LANGUAGE DeriveGeneric #-}
  {-# LANGUAGE DerivingVia #-}
  {-# LANGUAGE OverloadedStrings #-}
  {-# LANGUAGE PatternSynonyms #-}
  {-# LANGUAGE ScopedTypeVariables #-}
  {-# LANGUAGE StandaloneDeriving #-}
  
  module Grisette.Core.Data.Class.PPrintTests (pprintTests) where
  
  #if MIN_VERSION_prettyprinter(1,7,0)
  import Prettyprinter
    ( PageWidth(AvailablePerLine, Unbounded),
      layoutPretty,
      LayoutOptions(LayoutOptions),
    )
  import Prettyprinter.Render.Text (renderStrict)
  #else
  import Data.Text.Prettyprint.Doc
    ( PageWidth(AvailablePerLine, Unbounded),
      layoutPretty,
      LayoutOptions(LayoutOptions),
    )
  import Data.Text.Prettyprint.Doc.Render.Text (renderStrict)
  #endif
  
  import Control.Monad.Except (ExceptT (ExceptT))
  import Control.Monad.Identity (Identity (Identity), IdentityT (IdentityT))
  import Control.Monad.Trans.Maybe (MaybeT (MaybeT))
  import qualified Control.Monad.Trans.Writer.Lazy as WriterLazy
  import qualified Control.Monad.Writer.Strict as WriterStrict
  import qualified Data.HashMap.Lazy as HM
  import qualified Data.HashSet as HS
  import Data.Int (Int16, Int32, Int64, Int8)
  import Data.Text as T (Text, intercalate, pack, unpack)
  import Data.Word (Word16, Word32, Word64, Word8)
  import GHC.Generics (Generic, Generic1)
  import GHC.Stack (HasCallStack)
  import Generics.Deriving (Default (Default), Default1 (Default1))
  import Grisette
    ( IntN,
      LogicalOp ((.&&)),
      PPrint (pformat),
      SymBool,
      WordN,
      pattern SomeIntN,
      pattern SomeWordN,
    )
  import Grisette.Internal.Core.Data.Class.PPrint
    ( PPrint1,
      PPrint2,
      docToTextWithWidth,
      pformatPrec1,
      pformatPrec2,
      pformatTextWithWidth,
    )
  import Test.Framework (Test, testGroup)
  import Test.Framework.Providers.HUnit (testCase)
  import Test.Framework.Providers.QuickCheck2 (testProperty)
  import Test.HUnit ((@?=))
  import Test.QuickCheck (Arbitrary (arbitrary), Gen, forAll, oneof)
  
  testPPrint :: (HasCallStack, PPrint a) => String -> Int -> a -> T.Text -> Test
  testPPrint n i a s = testCase n $ pformatTextWithWidth i a @?= s
  
  testPPrint1 ::
    (HasCallStack, PPrint1 f, PPrint a) =>
    String ->
    Int ->
    f a ->
    T.Text ->
    Test
  testPPrint1 n i a s = testCase n $ do
    pformatTextWithWidth i a @?= s
    docToTextWithWidth i (pformatPrec1 0 a) @?= s
  
  testPPrint2 ::
    (HasCallStack, PPrint2 f, PPrint a, PPrint b) =>
    String ->
    Int ->
    f a b ->
    T.Text ->
    Test
  testPPrint2 n i a s = testCase n $ do
    pformatTextWithWidth i a @?= s
    docToTextWithWidth i (pformatPrec1 0 a) @?= s
    docToTextWithWidth i (pformatPrec2 0 a) @?= s
  
  propertyPFormatShow ::
    forall a.
    (PPrint a, Show a) =>
    String ->
    Gen a ->
    Test
  propertyPFormatShow n g =
    testProperty n $ forAll g $ \(a :: a) -> do
      renderStrict (layoutPretty (LayoutOptions Unbounded) (pformat a))
        == T.pack (show a)
  
  propertyPFormatRead ::
    forall a.
    (PPrint a, Read a, Show a, Eq a) =>
    String ->
    Gen a ->
    Test
  propertyPFormatRead n g =
    testProperty n $ \i -> forAll g $ \(a :: a) -> do
      read
        ( T.unpack
            ( renderStrict
                ( layoutPretty
                    (LayoutOptions $ AvailablePerLine (abs i) 0.8)
                    (pformat a)
                )
            )
        )
        == a
  
  data I5 a = a :-: a
    deriving (Generic, Show, Read, Eq)
    deriving (PPrint) via (Default (I5 a))
  
  infixl 5 :-:
  
  data I6 a = a :--: a
    deriving (Generic, Show, Read, Eq)
    deriving (PPrint) via (Default (I6 a))
  
  infixl 6 :--:
  
  instance
    (Arbitrary a) =>
    Arbitrary (I5 a)
    where
    arbitrary = do
      a <- arbitrary
      b <- arbitrary
      return $ a :-: b
  
  instance
    (Arbitrary a) =>
    Arbitrary (I6 a)
    where
    arbitrary = do
      a <- arbitrary
      b <- arbitrary
      return $ a :--: b
  
  data Record a b = Record {ra :: a, rb :: b}
    deriving (Generic, Show, Read, Eq)
    deriving (PPrint) via (Default (Record a b))
  
  instance
    (Arbitrary a, Arbitrary b) =>
    Arbitrary (Record a b)
    where
    arbitrary = do
      a <- arbitrary
      Record a <$> arbitrary
  
  data U1Test = U1Test
    deriving (Generic, Show, Read, Eq)
    deriving (PPrint) via (Default U1Test)
  
  newtype K1TestInt = K1Test Int
    deriving (Generic, Show, Read, Eq)
    deriving (PPrint) via (Default K1TestInt)
  
  newtype K1TestA a = K1TestA a
    deriving (Generic, Generic1, Show, Read, Eq, Functor)
    deriving (PPrint) via (Default (K1TestA a))
    deriving (PPrint1) via (Default1 K1TestA)
  
  newtype RecordK1TestA a = RecordK1TestA {recordK1TestA :: a}
    deriving (Generic, Show, Read, Eq)
    deriving (PPrint) via (Default (RecordK1TestA a))
  
  data SumTestAB a b = SumTestAB a b
    deriving (Generic, Generic1, Show, Read, Eq)
    deriving (PPrint) via (Default (SumTestAB a b))
    deriving (PPrint1) via (Default1 (SumTestAB a))
  
  data RecordSumTest a = RecordSumTest
    { recordSumTest1 :: a,
      recordSumTest2 :: a
    }
    deriving (Generic, Show, Read, Eq)
    deriving (PPrint) via (Default (RecordSumTest a))
  
  newtype Rec1Test f b = Rec1Test (f b)
    deriving (Generic, Generic1, Show, Eq)
  
  deriving via
    (Default (Rec1Test f a))
    instance
      (PPrint1 f, PPrint a) => PPrint (Rec1Test f a)
  
  deriving via
    (Default1 (Rec1Test f))
    instance
      (PPrint1 f) => PPrint1 (Rec1Test f)
  
  newtype Comp1Test f g b = Comp1Test (f (g b))
    deriving (Generic, Generic1, Show, Eq)
  
  deriving via
    (Default (Comp1Test f g a))
    instance
      (PPrint1 f, PPrint1 g, PPrint a) => PPrint (Comp1Test f g a)
  
  deriving via
    (Default1 (Comp1Test f g))
    instance
      (PPrint1 f, PPrint1 g, Functor f) => PPrint1 (Comp1Test f g)
  
  pprintTests :: Test
  pprintTests =
    testGroup
      "PPrint"
      [ testGroup
          "Derivation"
          [ testGroup
              "List"
              [ testPPrint1 "List Compact 0" 1 ([] :: [U1Test]) "[]",
                testPPrint1 "List Compact 1" 1 [U1Test] "[ U1Test\n]",
                testPPrint1 "List Compact 2" 1 [U1Test, U1Test] $
                  T.intercalate
                    "\n"
                    [ "[ U1Test,",
                      "  U1Test",
                      "]"
                    ],
                testPPrint1
                  "List Compact nested in 1"
                  1
                  [ [ U1Test,
                      U1Test
                    ]
                  ]
                  $ T.intercalate
                    "\n"
                    [ "[ [ U1Test,",
                      "    U1Test",
                      "  ]",
                      "]"
                    ],
                testPPrint1
                  "List Compact nested in >= 2"
                  1
                  [ [],
                    [U1Test],
                    [ U1Test,
                      U1Test
                    ]
                  ]
                  $ T.intercalate
                    "\n"
                    [ "[ [],",
                      "  [ U1Test",
                      "  ],",
                      "  [ U1Test,",
                      "    U1Test",
                      "  ]",
                      "]"
                    ],
                testPPrint1
                  "List unbounded nested"
                  0
                  [[], [U1Test], [U1Test, U1Test]]
                  "[[], [U1Test], [U1Test, U1Test]]"
              ],
            testGroup
              "U1"
              [ testPPrint "Unbounded" 0 U1Test "U1Test",
                testPPrint "Compact" 1 U1Test "U1Test",
                testPPrint "List Compact" 1 [U1Test, U1Test] $
                  T.intercalate
                    "\n"
                    [ "[ U1Test,",
                      "  U1Test",
                      "]"
                    ]
              ],
            testGroup
              "K1[Int]"
              [ testPPrint "Unbounded" 0 (K1Test 1) "K1Test 1",
                testPPrint "Compact" 1 (K1Test 1) "K1Test\n  1"
              ],
            testGroup
              "K1 U1"
              [ testPPrint1 "Unbounded" 0 (K1TestA U1Test) "K1TestA U1Test",
                testPPrint1 "Compact" 1 (K1TestA U1Test) "K1TestA\n  U1Test"
              ],
            testGroup
              "K1 (K1 Int)"
              [ testPPrint1
                  "Unbounded"
                  0
                  (K1TestA (K1Test 1))
                  "K1TestA (K1Test 1)",
                testPPrint1 "Compact" 1 (K1TestA (K1Test 1)) $
                  T.intercalate
                    "\n"
                    [ "K1TestA",
                      "  ( K1Test",
                      "      1",
                      "  )"
                    ]
              ],
            testGroup "K1 (I5 (K1 U1) (K1 U1))" $ do
              let value =
                    K1TestA
                      ( K1TestA
                          U1Test
                          :-: K1TestA
                            U1Test
                      )
              [ testPPrint1
                  "Unbounded"
                  0
                  value
                  "K1TestA (K1TestA U1Test :-: K1TestA U1Test)",
                testPPrint1 "Compact" 1 value $
                  T.intercalate
                    "\n"
                    [ "K1TestA",
                      "  ( K1TestA",
                      "      U1Test",
                      "      :-: K1TestA",
                      "        U1Test",
                      "  )"
                    ]
                ],
            testGroup "K1 (RecordK1 U1)" $ do
              let value =
                    K1TestA
                      ( RecordK1TestA
                          { recordK1TestA =
                              U1Test
                          }
                      )
              [ testPPrint1
                  "Unbounded"
                  0
                  value
                  "K1TestA (RecordK1TestA {recordK1TestA = U1Test})",
                testPPrint1 "Compact" 1 value $
                  T.intercalate
                    "\n"
                    [ "K1TestA",
                      "  ( RecordK1TestA",
                      "      { recordK1TestA =",
                      "          U1Test",
                      "      }",
                      "  )"
                    ]
                ],
            testGroup "K1 (RecordK1 (K1 U1))" $ do
              let value =
                    K1TestA
                      ( RecordK1TestA
                          { recordK1TestA =
                              K1TestA
                                U1Test
                          }
                      )
              [ testPPrint1
                  "Unbounded"
                  0
                  value
                  "K1TestA (RecordK1TestA {recordK1TestA = K1TestA U1Test})",
                testPPrint1 "Compact" 1 value $
                  T.intercalate
                    "\n"
                    [ "K1TestA",
                      "  ( RecordK1TestA",
                      "      { recordK1TestA =",
                      "          K1TestA",
                      "            U1Test",
                      "      }",
                      "  )"
                    ]
                ],
            testGroup "K1 (RecordSum (K1 U1))" $ do
              let value =
                    K1TestA
                      ( RecordSumTest
                          { recordSumTest1 =
                              K1TestA
                                U1Test,
                            recordSumTest2 =
                              K1TestA
                                U1Test
                          }
                      )
              [ testPPrint1 "Unbounded" 0 value $
                  "K1TestA (RecordSumTest {recordSumTest1 = K1TestA U1Test, "
                    <> "recordSumTest2 = K1TestA U1Test})",
                testPPrint1 "Compact" 1 value $
                  T.intercalate
                    "\n"
                    [ "K1TestA",
                      "  ( RecordSumTest",
                      "      { recordSumTest1 =",
                      "          K1TestA",
                      "            U1Test,",
                      "        recordSumTest2 =",
                      "          K1TestA",
                      "            U1Test",
                      "      }",
                      "  )"
                    ]
                ],
            testGroup "K1 (K1 U1, K1 U1)" $ do
              let value =
                    K1TestA
                      ( K1TestA
                          U1Test,
                        K1TestA
                          U1Test
                      )
              [ testPPrint1
                  "Unbounded"
                  0
                  value
                  "K1TestA (K1TestA U1Test, K1TestA U1Test)",
                testPPrint1 "Compact" 1 value $
                  T.intercalate
                    "\n"
                    [ "K1TestA",
                      "  ( K1TestA",
                      "      U1Test,",
                      "    K1TestA",
                      "      U1Test",
                      "  )"
                    ]
                ],
            testGroup "Sum (K1 U1) (K1 U1)" $ do
              let value = SumTestAB (K1TestA U1Test) U1Test
              [ testPPrint1
                  "Unbounded"
                  0
                  value
                  "SumTestAB (K1TestA U1Test) U1Test",
                testPPrint1 "Compact" 1 value $
                  T.intercalate
                    "\n"
                    [ "SumTestAB",
                      "  ( K1TestA",
                      "      U1Test",
                      "  )",
                      "  U1Test"
                    ]
                ],
            testGroup "Rec1 K1 (K1 U1)" $ do
              let value =
                    Rec1Test
                      ( K1TestA
                          ( K1TestA
                              U1Test
                          )
                      )
              [ testPPrint1
                  "Unbounded"
                  0
                  value
                  "Rec1Test (K1TestA (K1TestA U1Test))",
                testPPrint1 "Compact" 1 value $
                  T.intercalate
                    "\n"
                    [ "Rec1Test",
                      "  ( K1TestA",
                      "      ( K1TestA",
                      "          U1Test",
                      "      )",
                      "  )"
                    ]
                ],
            testGroup "Comp1 K1 K1 (K1 U1)" $ do
              let value =
                    Comp1Test
                      ( K1TestA
                          ( K1TestA
                              ( K1TestA
                                  U1Test
                              )
                          )
                      )
              [ testPPrint1
                  "Unbounded"
                  0
                  value
                  "Comp1Test (K1TestA (K1TestA (K1TestA U1Test)))",
                testPPrint1 "Compact" 1 value $
                  T.intercalate
                    "\n"
                    [ "Comp1Test",
                      "  ( K1TestA",
                      "      ( K1TestA",
                      "          ( K1TestA",
                      "              U1Test",
                      "          )",
                      "      )",
                      "  )"
                    ]
                ],
            testGroup "Comp1 [] [] (K1 U1)" $ do
              let value =
                    Comp1Test
                      [ [ K1TestA
                            U1Test,
                          K1TestA
                            U1Test
                        ]
                      ]
              [ testPPrint1
                  "Unbounded"
                  0
                  value
                  "Comp1Test [[K1TestA U1Test, K1TestA U1Test]]",
                testPPrint1 "Compact" 1 value $
                  T.intercalate
                    "\n"
                    [ "Comp1Test",
                      "  [ [ K1TestA",
                      "        U1Test,",
                      "      K1TestA",
                      "        U1Test",
                      "    ]",
                      "  ]"
                    ]
                ]
          ],
        testGroup
          "PPrint2"
          [ testGroup
              "Either"
              [ testPPrint2
                  "Unbounded Left"
                  0
                  (Left (K1TestA U1Test) :: Either (K1TestA U1Test) ())
                  "Left (K1TestA U1Test)",
                testPPrint2
                  "Unbounded Right"
                  0
                  (Right (K1TestA U1Test) :: Either () (K1TestA U1Test))
                  "Right (K1TestA U1Test)",
                testPPrint2
                  "Compact Left"
                  1
                  (Left (K1TestA U1Test) :: Either (K1TestA U1Test) ())
                  "Left\n  ( K1TestA\n      U1Test\n  )",
                testPPrint2
                  "Compact Right"
                  1
                  (Right (K1TestA U1Test) :: Either () (K1TestA U1Test))
                  "Right\n  ( K1TestA\n      U1Test\n  )"
              ],
            testGroup "(,)" $ do
              let value =
                    (K1TestA U1Test, K1TestA U1Test) ::
                      (K1TestA U1Test, K1TestA U1Test)
              [ testPPrint2
                  "Unbounded"
                  0
                  value
                  "(K1TestA U1Test, K1TestA U1Test)",
                testPPrint2
                  "Compact"
                  1
                  value
                  "( K1TestA\n    U1Test,\n  K1TestA\n    U1Test\n)"
                ]
          ],
        testGroup
          "simple tests"
          [ propertyPFormatRead "Bool" (arbitrary :: Gen Bool),
            propertyPFormatRead "Integer" (arbitrary :: Gen Integer),
            propertyPFormatRead "Int" (arbitrary :: Gen Int),
            propertyPFormatRead "Int8" (arbitrary :: Gen Int8),
            propertyPFormatRead "Int16" (arbitrary :: Gen Int16),
            propertyPFormatRead "Int32" (arbitrary :: Gen Int32),
            propertyPFormatRead "Int64" (arbitrary :: Gen Int64),
            propertyPFormatRead "Word" (arbitrary :: Gen Word),
            propertyPFormatRead "Word8" (arbitrary :: Gen Word8),
            propertyPFormatRead "Word16" (arbitrary :: Gen Word16),
            propertyPFormatRead "Word32" (arbitrary :: Gen Word32),
            propertyPFormatRead "Word64" (arbitrary :: Gen Word64),
            propertyPFormatShow
              "SomeWordN"
              ( oneof
                  [ SomeWordN <$> (arbitrary :: Gen (WordN 8)),
                    SomeWordN <$> (arbitrary :: Gen (WordN 9)),
                    SomeWordN <$> (arbitrary :: Gen (WordN 10))
                  ]
              ),
            propertyPFormatRead "WordN 8" (arbitrary :: Gen (WordN 8)),
            propertyPFormatRead "WordN 9" (arbitrary :: Gen (WordN 9)),
            propertyPFormatShow
              "SomeIntN"
              ( oneof
                  [ SomeIntN <$> (arbitrary :: Gen (IntN 8)),
                    SomeIntN <$> (arbitrary :: Gen (IntN 9)),
                    SomeIntN <$> (arbitrary :: Gen (IntN 10))
                  ]
              ),
            propertyPFormatRead "IntN 8" (arbitrary :: Gen (IntN 8)),
            propertyPFormatRead "IntN 9" (arbitrary :: Gen (IntN 9))
          ],
        testGroup
          "Combined types"
          [ propertyPFormatRead
              "Maybe Maybe"
              (arbitrary :: Gen (Maybe (Maybe Int))),
            propertyPFormatRead
              "Maybe (,)"
              (arbitrary :: Gen (Maybe (Int, Int))),
            propertyPFormatRead
              "Maybe I5"
              (arbitrary :: Gen (Maybe (I5 Int))),
            propertyPFormatRead
              "Maybe []"
              (arbitrary :: Gen (Maybe [Int])),
            propertyPFormatRead
              "Maybe Record"
              (arbitrary :: Gen (Maybe (Record Int Int))),
            propertyPFormatRead
              "(Maybe,Either)"
              (arbitrary :: Gen (Maybe Int, Either Int Int)),
            propertyPFormatRead
              "((,),(,))"
              (arbitrary :: Gen ((Int, Int), (Int, Int))),
            propertyPFormatRead
              "(I5,I5)"
              (arbitrary :: Gen (I5 Int, I5 Int)),
            propertyPFormatRead
              "([],[])"
              (arbitrary :: Gen ([Int], [Int])),
            propertyPFormatRead
              "(Record,Record)"
              (arbitrary :: Gen (Record Int Int, Record Int Int)),
            propertyPFormatRead "I5 (,)" (arbitrary :: Gen (I5 (Int, Int))),
            propertyPFormatRead "I5 I6" (arbitrary :: Gen (I5 (I6 Int))),
            propertyPFormatRead "I5 I5" (arbitrary :: Gen (I5 (I5 Int))),
            propertyPFormatRead "I6 I5" (arbitrary :: Gen (I6 (I5 Int))),
            propertyPFormatRead "I6 I6" (arbitrary :: Gen (I6 (I6 Int))),
            propertyPFormatRead "I5 []" (arbitrary :: Gen (I5 [Int])),
            propertyPFormatRead
              "I5 Record"
              (arbitrary :: Gen (I5 (Record Int Int))),
            propertyPFormatRead
              "[Maybe]"
              (arbitrary :: Gen [Maybe Int]),
            propertyPFormatRead
              "[(,)]"
              (arbitrary :: Gen [(Int, Int)]),
            propertyPFormatRead "[I5]" (arbitrary :: Gen [I5 Int]),
            propertyPFormatRead
              "[[]]"
              (arbitrary :: Gen [[Int]]),
            propertyPFormatRead
              "[Record]"
              (arbitrary :: Gen [Record Int Int]),
            propertyPFormatRead
              "Record Maybe Either"
              (arbitrary :: Gen (Record (Maybe Int) (Either Int Int))),
            propertyPFormatRead
              "Record (,) (,)"
              (arbitrary :: Gen (Record (Int, Int) (Int, Int))),
            propertyPFormatRead
              "Record I5 I6"
              (arbitrary :: Gen (Record (I5 Int) (I6 Int))),
            propertyPFormatRead
              "Record []"
              (arbitrary :: Gen (Record [Int] [Int])),
            propertyPFormatRead
              "Record Record"
              (arbitrary :: Gen (Record (Record Int Int) (Record Int Int))),
            testPPrint1
              "Identity"
              0
              (Identity $ Just $ Just 1 :: Identity (Maybe (Maybe Int)))
              "Just (Just 1)",
            testPPrint1
              "Maybe (MaybeT Maybe Int)"
              0
              (Just $ MaybeT (Just (Just 1)) :: Maybe (MaybeT Maybe Int))
              "Just (MaybeT {runMaybeT = Just (Just 1)})",
            propertyPFormatRead
              "Maybe (ExceptT Int Maybe Int)"
              ( Just . ExceptT <$> arbitrary ::
                  Gen (Maybe (ExceptT Int Maybe Int))
              ),
            testPPrint1
              "Maybe (LazyWriterT Int Maybe Int)"
              0
              ( Just $ WriterLazy.WriterT (Just (1, 2)) ::
                  Maybe (WriterLazy.WriterT Int Maybe Int)
              )
              "Just (WriterT {runWriterT = Just (1, 2)})",
            testPPrint1
              "Maybe (StrictWriterT Int Maybe Int)"
              0
              ( Just $ WriterStrict.WriterT (Just (1, 2)) ::
                  Maybe (WriterStrict.WriterT Int Maybe Int)
              )
              "Just (WriterT {runWriterT = Just (1, 2)})",
            propertyPFormatRead
              "Maybe (IdentityT Maybe Int)"
              ( Just . IdentityT <$> arbitrary ::
                  Gen (Maybe (IdentityT Maybe Int))
              ),
            testGroup
              "HashSet"
              [ testPPrint1
                  "Unbounded empty"
                  0
                  (HS.fromList [] :: HS.HashSet Int)
                  "HashSet []",
                testPPrint1
                  "Unbounded singleton"
                  0
                  (HS.fromList [1] :: HS.HashSet Int)
                  "HashSet [1]",
                testPPrint1
                  "Unbounded two elem"
                  0
                  (HS.fromList [1, 2] :: HS.HashSet Int)
                  "HashSet [1, 2]",
                testPPrint1
                  "Compact empty"
                  1
                  (HS.fromList [] :: HS.HashSet Int)
                  "HashSet\n  []",
                testPPrint1
                  "Compact singleton"
                  1
                  (HS.fromList [1] :: HS.HashSet Int)
                  "HashSet\n  [ 1\n  ]",
                testPPrint1
                  "Unbounded two elem"
                  1
                  (HS.fromList [1, 2] :: HS.HashSet Int)
                  "HashSet\n  [ 1,\n    2\n  ]"
              ],
            testGroup
              "HashMap"
              [ testPPrint1
                  "Unbounded empty"
                  0
                  (HM.fromList [] :: HM.HashMap Int Int)
                  "HashMap []",
                testPPrint1
                  "Unbounded singleton"
                  0
                  (HM.fromList [(1, 2)] :: HM.HashMap Int Int)
                  "HashMap [(1, 2)]",
                testPPrint1
                  "Unbounded two elem"
                  0
                  (HM.fromList [(1, 2), (3, 4)] :: HM.HashMap Int Int)
                  "HashMap [(1, 2), (3, 4)]",
                testPPrint1
                  "Compact empty"
                  1
                  (HM.fromList [] :: HM.HashMap Int Int)
                  "HashMap\n  []",
                testPPrint1
                  "Compact singleton"
                  1
                  (HM.fromList [(1, 2)] :: HM.HashMap Int Int)
                  ( T.intercalate
                      "\n"
                      [ "HashMap",
                        "  [ ( 1,",
                        "      2",
                        "    )",
                        "  ]"
                      ]
                  ),
                testPPrint1
                  "Unbounded two elem"
                  1
                  (HM.fromList [(1, 2), (3, 4)] :: HM.HashMap Int Int)
                  ( T.intercalate
                      "\n"
                      [ "HashMap",
                        "  [ ( 1,",
                        "      2",
                        "    ),",
                        "    ( 3,",
                        "      4",
                        "    )",
                        "  ]"
                      ]
                  )
              ]
          ],
        testGroup
          "Symbolic types"
          [ testPPrint
              "enough space"
              80
              ("a" .&& "b" :: SymBool)
              "(&& a b)",
            testPPrint
              "not enough space"
              6
              ("a" .&& "b" :: SymBool)
              "..."
          ]
      ]
  