module Test.Hspec.Expectations.Matcher (matchList) where

import           Prelude hiding (showList)
import           Data.List

matchList :: (Show a, Eq a) => [a] -> [a] -> Maybe String
[a]
xs matchList :: forall a. (Show a, Eq a) => [a] -> [a] -> Maybe String
`matchList` [a]
ys
  | [a] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [a]
extra Bool -> Bool -> Bool
&& [a] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [a]
missing = Maybe String
forall a. Maybe a
Nothing
  | Bool
otherwise = String -> Maybe String
forall a. a -> Maybe a
Just (ShowS
err String
"")
  where
    extra :: [a]
extra   = [a]
xs [a] -> [a] -> [a]
forall a. Eq a => [a] -> [a] -> [a]
\\ [a]
ys
    missing :: [a]
missing = [a]
ys [a] -> [a] -> [a]
forall a. Eq a => [a] -> [a] -> [a]
\\ [a]
xs

    msgAndList :: String -> [a] -> ShowS
msgAndList String
msg [a]
zs = String -> ShowS
showString String
msg ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [a] -> ShowS
forall a. Show a => [a] -> ShowS
showList [a]
zs ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> ShowS
showString String
"\n"
    optMsgList :: String -> [a] -> ShowS
optMsgList String
msg [a]
zs = if [a] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [a]
zs then ShowS
forall a. a -> a
id else String -> [a] -> ShowS
forall {a}. Show a => String -> [a] -> ShowS
msgAndList String
msg [a]
zs

    err :: ShowS
    err :: ShowS
err =
        String -> ShowS
showString String
"Actual list is not a permutation of expected list!\n"
      ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> [a] -> ShowS
forall {a}. Show a => String -> [a] -> ShowS
msgAndList String
"  expected elements: " [a]
ys
      ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> [a] -> ShowS
forall {a}. Show a => String -> [a] -> ShowS
msgAndList String
"  actual elements:   " [a]
xs
      ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> [a] -> ShowS
forall {a}. Show a => String -> [a] -> ShowS
optMsgList String
"  missing elements:  " [a]
missing
      ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> [a] -> ShowS
forall {a}. Show a => String -> [a] -> ShowS
optMsgList String
"  extra elements:    " [a]
extra

showList :: Show a => [a] -> ShowS
showList :: forall a. Show a => [a] -> ShowS
showList [a]
xs = Char -> ShowS
showChar Char
'[' ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ShowS -> ShowS -> ShowS) -> ShowS -> [ShowS] -> ShowS
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
(.) (Char -> ShowS
showChar Char
']') (ShowS -> [ShowS] -> [ShowS]
forall a. a -> [a] -> [a]
intersperse (String -> ShowS
showString String
", ") ([ShowS] -> [ShowS]) -> [ShowS] -> [ShowS]
forall a b. (a -> b) -> a -> b
$ (a -> ShowS) -> [a] -> [ShowS]
forall a b. (a -> b) -> [a] -> [b]
map a -> ShowS
forall a. Show a => a -> ShowS
shows [a]
xs)