uccess :: S.State -> IO ()
success st =
  case allLabels ++ covers of
    []    -> do putLine (S.terminal st) "."
    [pt]  -> do putLine (S.terminal st)
                  ( " ("
                 ++ dropWhile isSpace pt
                 ++ ")."
                  )
    cases -> do putLine (S.terminal st) ":"
                sequence_ [ putLine (S.terminal st) pt | pt <- cases ]
 where
  allLabels = reverse
            . sort
            . map (\ss -> (showP ((length ss * 100) `div` S.numSuccessTests st) ++ head ss))
            . group
            . sort
            $ [ concat (intersperse ", " s')
              | s <- S.collected st
              , let s' = [ t | t <- Set.toList s, M.lookup t (S.labels st) == Just 0 ]
              , not (null s')
              ]

  covers = [ ("only " ++ show (labelPercentage l st) ++ "% " ++ l ++ ", not " ++ show reqP ++ "%")
           | (l, reqP) <- M.toList (S.labels st)
           , labelPercentage l st < reqP
           ]

  -- (x,_) `first` (y,_) = x == y

  showP p = (if p < 10 then " " else "") ++ show p ++ "% "

success :: S.State -> IO ()
success st =
  case allLabels ++ covers of
    []    -> do putLine (S.terminal st) "."
    [pt]  -> do putLine (S.terminal st)
                  ( " ("
                 ++ dropWhile isSpace pt
                 ++ ")."
                  )
    cases -> do putLine (S.terminal st) ":"
                sequence_ [ putLine (S.terminal st) pt | pt <- cases ]
 where
  allLabels = reverse
            . sort
            . map (\ss -> (showP ((length ss * 100) `div` S.numSuccessTests st) ++ head ss))
            . group
            . sort
            $ [ concat (intersperse ", " s')
              | s <- S.collected st
              , let s' = [ t | t <- Set.toList s, M.lookup t (S.labels st) == Just 0 ]
              , not (null s')
              ]

  covers = [ ("only " ++ show (labelPercentage l st) ++ "% " ++ l ++ ", not " ++ show reqP ++ "%")
           | (l, reqP) <- M.toList (S.labels st)
           , labelPercentage l st < reqP
           ]

  -- (x,_) `first` (y,_) = x == y

  showP p = (if p < 10 then " " else "") ++ show p ++ "% "
success st =
  case allLabels ++ covers of
    []    -> do putLine (S.terminal st) "."
    [pt]  -> do putLine (S.terminal st)
                  ( " ("
                 ++ dropWhile isSpace pt
                 ++ ")."
                  )
    cases -> do putLine (S.terminal st) ":"
                sequence_ [ putLine (S.terminal st) pt | pt <- cases ]
 where
  allLabels = reverse
            . sort
            . map (\ss -> (showP ((length ss * 100) `div` S.numSuccessTests st) ++ head ss))
            . group
            . sort
            $ [ concat (intersperse ", " s')
              | s <- S.collected st
              , let s' = [ t | t <- Set.toList s, M.lookup t (S.labels st) == Just 0 ]
              , not (null s')
              ]

  covers = [ ("only " ++ show (labelPercentage l st) ++ "% " ++ l ++ ", not " ++ show reqP ++ "%")
           | (l, reqP) <- M.toList (S.labels st)
           , labelPercentage l st < reqP
           ]

  -- (x,_) `first` (y,_) = x == y

  showP p = (if p < 10 then " " else "") ++ show p ++ "% "