content: import Control.Monad (forM_)
  import Data.List
  
  import Test.HUnit
  
  import qualified Portage.Dependency as P
  import qualified Portage.Dependency.Normalize as PN
  import qualified Portage.PackageId  as P
  import qualified Portage.Use  as P
  import qualified RunTests as RT
  
  tests :: Test
  tests = TestList [ TestLabel "print_empty" test_print_empty
                   , TestLabel "print_mixed" test_print_mixed
                   , TestLabel "print_denorm" test_print_denorm
                   ]
  
  test_print_empty :: Test
  test_print_empty = TestCase $ do
      let expect_empty = ""
          d_all = P.DependAllOf
          d_any = P.DependAnyOf
          d_use u dep = P.mkUseDependency (True, P.Use u) dep
          deps     = [ d_all []
                     , d_any []
                     , d_use "f" (d_all [])
                     , P.DependAllOf [d_any []]
                     , P.DependAnyOf [d_all []]
                     -- Deep Useless Use Tree :]
                     , d_use "f" $
                         d_use "g" $
                             d_all [d_any []
                                   , d_use "h" $
                                       d_all [ d_all []
                                             , d_any []
                                             ]
                                   , d_use "i" $
                                       d_all [ d_all []
                                             , d_any []
                                             ]
                                   ]
                     ]
      forM_ deps $ \d ->
          let actual_result = P.dep2str 0 $ PN.normalize_depend d
          in assertEqual ("expecting empty result for " ++ show d)
                         expect_empty
                         actual_result
  
  test_print_mixed :: Test
  test_print_mixed = TestCase $ do
      let pn = P.mkPackageName "dev-haskell" "mtl"
          def_attr = P.DAttr P.AnySlot []
          p_v v = P.Version { P.versionNumber   = v
                            , P.versionChar     = Nothing
                            , P.versionSuffix   = []
                            , P.versionRevision = 0
                            }
          d_all = P.DependAllOf
          d_any = P.DependAnyOf
          d_ge v = P.DependAtom $ P.Atom pn
                          (P.DRange (P.NonstrictLB $ p_v v) P.InfinityB)
                          def_attr
          d_lt v = P.DependAtom $ P.Atom pn
                          (P.DRange P.ZeroB (P.StrictUB $ p_v v))
                          def_attr
          deps  = [ -- from agda: "mtl ==2.0.* || >=2.1.1 && <2.2"
                    ( d_all [ d_any [ d_all [ d_ge [2, 0]
                                            , d_lt [2, 1]
                                            ]
                                    , d_all [ d_ge [2, 1, 1]
                                            , d_lt [2, 2]
                                            ]
                                    ]
                            ]
                    , [ "|| ( ( >=dev-haskell/mtl-2.0 <dev-haskell/mtl-2.1 )"
                      , "     ( >=dev-haskell/mtl-2.1.1 <dev-haskell/mtl-2.2 ) )"
                      ]
                    )
                  -- remove duplicate entries
                  , ( let d = d_all [d_ge [2, 0], d_lt [2, 2]]
                      in d_all [d, d]
                    , [ ">=dev-haskell/mtl-2.0 <dev-haskell/mtl-2.2" ]
                    )
                  ]
      forM_ deps $ \(d, expected) ->
          let actual = P.dep2str 0 $ PN.normalize_depend d
          in assertEqual ("expecting empty result for " ++ show d)
                         (intercalate "\n" expected)
                         actual
  
  test_print_denorm :: Test
  test_print_denorm = TestCase $ do
      let pn = P.mkPackageName "dev-haskell" "mtl"
          def_attr = P.DAttr P.AnySlot []
          p_v v = P.Version { P.versionNumber   = v
                            , P.versionChar     = Nothing
                            , P.versionSuffix   = []
                            , P.versionRevision = 0
                            }
          d_all = P.DependAllOf
          d_any = P.DependAnyOf
          d_ge v = P.DependAtom $ P.Atom pn
                          (P.DRange (P.NonstrictLB $ p_v v) P.InfinityB)
                          def_attr
          d_lt v = P.DependAtom $ P.Atom pn
                          (P.DRange P.ZeroB (P.StrictUB $ p_v v))
                          def_attr
          deps  = [ -- from agda: "mtl ==2.0.* || >=2.1.1 && <2.2"
                    ( d_all [ d_any [ d_all [ d_ge [2, 0]
                                            , d_lt [2, 1]
                                            ]
                                    , d_all [ d_ge [2, 1, 1]
                                            , d_lt [2, 2]
                                            ]
                                    ]
                            ]
                    , [ "|| ( ( >=dev-haskell/mtl-2.0"
                      , "       <dev-haskell/mtl-2.1 )"
                      , "     ( >=dev-haskell/mtl-2.1.1"
                      , "       <dev-haskell/mtl-2.2 ) )"
                      ]
                    )
                  -- remove duplicate entries
                  , ( let d = d_all [d_ge [2, 0], d_lt [2, 2]]
                      in d_all [d, d]
                    , [ ">=dev-haskell/mtl-2.0"
                      , "<dev-haskell/mtl-2.2"
                      , ">=dev-haskell/mtl-2.0"
                      , "<dev-haskell/mtl-2.2"
                      ]
                    )
                  ]
      forM_ deps $ \(d, expected) ->
          let actual = P.dep2str_noindent d
          in assertEqual ("expecting empty result for " ++ show d)
                         (intercalate "\n" expected)
                         actual
  
  main :: IO ()
  main = RT.run_tests tests
  