{-# LANGUAGE RankNTypes #-}
module Expect
(
Expectation,
equal,
notEqual,
all,
equalToContentsOf,
FloatingPointTolerance (..),
within,
notWithin,
lessThan,
atMost,
greaterThan,
atLeast,
true,
false,
ok,
err,
pass,
fail,
onFail,
fromResult,
succeeds,
fails,
andCheck,
fromIO,
Internal.Expectation',
around,
)
where
import qualified Data.Text
import qualified Data.Text.IO
import qualified Debug
import qualified GHC.Stack as Stack
import qualified List
import NriPrelude
import qualified Platform.Internal
import qualified Pretty.Diff as Diff
import qualified System.Console.Terminal.Size as Terminal
import qualified System.Directory as Directory
import qualified System.FilePath as FilePath
import qualified Task
import Test.Internal (Expectation)
import qualified Test.Internal as Internal
import qualified Text.Show.Pretty
import qualified Prelude
pass :: Stack.HasCallStack => Expectation
pass :: Expectation
pass = (HasCallStack => Text -> () -> Expectation)
-> Text -> () -> Expectation
forall a. HasCallStack => (HasCallStack => a) -> a
Stack.withFrozenCallStack HasCallStack => Text -> () -> Expectation
forall a. HasCallStack => Text -> a -> Expectation' a
Internal.pass Text
"Expect.pass" ()
fail :: Stack.HasCallStack => Text -> Expectation
fail :: Text -> Expectation
fail Text
msg =
(HasCallStack => Text -> Text -> Expectation)
-> Text -> Text -> Expectation
forall a. HasCallStack => (HasCallStack => a) -> a
Stack.withFrozenCallStack HasCallStack => Text -> Text -> Expectation
forall a. HasCallStack => Text -> Text -> Expectation' a
Internal.failAssertion Text
"Expect.fail" Text
msg
onFail :: Stack.HasCallStack => Text -> Expectation -> Expectation
onFail :: Text -> Expectation -> Expectation
onFail Text
msg (Internal.Expectation Task Failure ()
task) =
Task Failure ()
task
Task Failure ()
-> (Task Failure () -> Task Failure ()) -> Task Failure ()
forall a b. a -> (a -> b) -> b
|> (Failure -> Task Failure ()) -> Task Failure () -> Task Failure ()
forall x y a. (x -> Task y a) -> Task x a -> Task y a
Task.onError
( \Failure
_ ->
(HasCallStack => Text -> Text -> Expectation)
-> Text -> Text -> Expectation
forall a. HasCallStack => (HasCallStack => a) -> a
Stack.withFrozenCallStack HasCallStack => Text -> Text -> Expectation
forall a. HasCallStack => Text -> Text -> Expectation' a
Internal.failAssertion Text
"Expect.onFail" Text
msg
Expectation -> (Expectation -> Task Failure ()) -> Task Failure ()
forall a b. a -> (a -> b) -> b
|> Expectation -> Task Failure ()
forall a. Expectation' a -> Task Failure a
Internal.unExpectation
)
Task Failure () -> (Task Failure () -> Expectation) -> Expectation
forall a b. a -> (a -> b) -> b
|> Task Failure () -> Expectation
forall a. Task Failure a -> Expectation' a
Internal.Expectation
equal :: (Stack.HasCallStack, Show a, Eq a) => a -> a -> Expectation
equal :: a -> a -> Expectation
equal = (HasCallStack => (a -> a -> Bool) -> Text -> a -> a -> Expectation)
-> (a -> a -> Bool) -> Text -> a -> a -> Expectation
forall a. HasCallStack => (HasCallStack => a) -> a
Stack.withFrozenCallStack HasCallStack => (a -> a -> Bool) -> Text -> a -> a -> Expectation
forall a.
(HasCallStack, Show a) =>
(a -> a -> Bool) -> Text -> a -> a -> Expectation
assert a -> a -> Bool
forall a. Eq a => a -> a -> Bool
(==) Text
"Expect.equal"
notEqual :: (Stack.HasCallStack, Show a, Eq a) => a -> a -> Expectation
notEqual :: a -> a -> Expectation
notEqual = (HasCallStack => (a -> a -> Bool) -> Text -> a -> a -> Expectation)
-> (a -> a -> Bool) -> Text -> a -> a -> Expectation
forall a. HasCallStack => (HasCallStack => a) -> a
Stack.withFrozenCallStack HasCallStack => (a -> a -> Bool) -> Text -> a -> a -> Expectation
forall a.
(HasCallStack, Show a) =>
(a -> a -> Bool) -> Text -> a -> a -> Expectation
assert a -> a -> Bool
forall a. Eq a => a -> a -> Bool
(/=) Text
"Expect.notEqual"
lessThan :: (Stack.HasCallStack, Show a, Ord a) => a -> a -> Expectation
lessThan :: a -> a -> Expectation
lessThan = (HasCallStack => (a -> a -> Bool) -> Text -> a -> a -> Expectation)
-> (a -> a -> Bool) -> Text -> a -> a -> Expectation
forall a. HasCallStack => (HasCallStack => a) -> a
Stack.withFrozenCallStack HasCallStack => (a -> a -> Bool) -> Text -> a -> a -> Expectation
forall a.
(HasCallStack, Show a) =>
(a -> a -> Bool) -> Text -> a -> a -> Expectation
assert a -> a -> Bool
forall comparable.
Ord comparable =>
comparable -> comparable -> Bool
(>) Text
"Expect.lessThan"
atMost :: (Stack.HasCallStack, Show a, Ord a) => a -> a -> Expectation
atMost :: a -> a -> Expectation
atMost = (HasCallStack => (a -> a -> Bool) -> Text -> a -> a -> Expectation)
-> (a -> a -> Bool) -> Text -> a -> a -> Expectation
forall a. HasCallStack => (HasCallStack => a) -> a
Stack.withFrozenCallStack HasCallStack => (a -> a -> Bool) -> Text -> a -> a -> Expectation
forall a.
(HasCallStack, Show a) =>
(a -> a -> Bool) -> Text -> a -> a -> Expectation
assert a -> a -> Bool
forall comparable.
Ord comparable =>
comparable -> comparable -> Bool
(>=) Text
"Expect.atMost"
greaterThan :: (Stack.HasCallStack, Show a, Ord a) => a -> a -> Expectation
greaterThan :: a -> a -> Expectation
greaterThan = (HasCallStack => (a -> a -> Bool) -> Text -> a -> a -> Expectation)
-> (a -> a -> Bool) -> Text -> a -> a -> Expectation
forall a. HasCallStack => (HasCallStack => a) -> a
Stack.withFrozenCallStack HasCallStack => (a -> a -> Bool) -> Text -> a -> a -> Expectation
forall a.
(HasCallStack, Show a) =>
(a -> a -> Bool) -> Text -> a -> a -> Expectation
assert a -> a -> Bool
forall comparable.
Ord comparable =>
comparable -> comparable -> Bool
(<) Text
"Expect.greaterThan"
atLeast :: (Stack.HasCallStack, Show a, Ord a) => a -> a -> Expectation
atLeast :: a -> a -> Expectation
atLeast = (HasCallStack => (a -> a -> Bool) -> Text -> a -> a -> Expectation)
-> (a -> a -> Bool) -> Text -> a -> a -> Expectation
forall a. HasCallStack => (HasCallStack => a) -> a
Stack.withFrozenCallStack HasCallStack => (a -> a -> Bool) -> Text -> a -> a -> Expectation
forall a.
(HasCallStack, Show a) =>
(a -> a -> Bool) -> Text -> a -> a -> Expectation
assert a -> a -> Bool
forall comparable.
Ord comparable =>
comparable -> comparable -> Bool
(<=) Text
"Expect.atLeast"
data FloatingPointTolerance
= Absolute Float
| Relative Float
| AbsoluteOrRelative Float Float
deriving (Int -> FloatingPointTolerance -> ShowS
[FloatingPointTolerance] -> ShowS
FloatingPointTolerance -> String
(Int -> FloatingPointTolerance -> ShowS)
-> (FloatingPointTolerance -> String)
-> ([FloatingPointTolerance] -> ShowS)
-> Show FloatingPointTolerance
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [FloatingPointTolerance] -> ShowS
$cshowList :: [FloatingPointTolerance] -> ShowS
show :: FloatingPointTolerance -> String
$cshow :: FloatingPointTolerance -> String
showsPrec :: Int -> FloatingPointTolerance -> ShowS
$cshowsPrec :: Int -> FloatingPointTolerance -> ShowS
Show)
within :: (Stack.HasCallStack) => FloatingPointTolerance -> Float -> Float -> Expectation
within :: FloatingPointTolerance -> Float -> Float -> Expectation
within FloatingPointTolerance
tolerance =
(HasCallStack =>
(Float -> Float -> Bool) -> Text -> Float -> Float -> Expectation)
-> (Float -> Float -> Bool)
-> Text
-> Float
-> Float
-> Expectation
forall a. HasCallStack => (HasCallStack => a) -> a
Stack.withFrozenCallStack
HasCallStack =>
(Float -> Float -> Bool) -> Text -> Float -> Float -> Expectation
forall a.
(HasCallStack, Show a) =>
(a -> a -> Bool) -> Text -> a -> a -> Expectation
assert
(FloatingPointTolerance -> Float -> Float -> Bool
withinHelper FloatingPointTolerance
tolerance)
(Text
"Expect.within " Text -> Text -> Text
forall appendable.
Semigroup appendable =>
appendable -> appendable -> appendable
++ String -> Text
Data.Text.pack (FloatingPointTolerance -> String
forall a. Show a => a -> String
Prelude.show FloatingPointTolerance
tolerance))
notWithin :: (Stack.HasCallStack) => FloatingPointTolerance -> Float -> Float -> Expectation
notWithin :: FloatingPointTolerance -> Float -> Float -> Expectation
notWithin FloatingPointTolerance
tolerance =
(HasCallStack =>
(Float -> Float -> Bool) -> Text -> Float -> Float -> Expectation)
-> (Float -> Float -> Bool)
-> Text
-> Float
-> Float
-> Expectation
forall a. HasCallStack => (HasCallStack => a) -> a
Stack.withFrozenCallStack
HasCallStack =>
(Float -> Float -> Bool) -> Text -> Float -> Float -> Expectation
forall a.
(HasCallStack, Show a) =>
(a -> a -> Bool) -> Text -> a -> a -> Expectation
assert
(\Float
expected Float
actual -> Bool -> Bool
not (FloatingPointTolerance -> Float -> Float -> Bool
withinHelper FloatingPointTolerance
tolerance Float
expected Float
actual))
(Text
"Expect.notWithin " Text -> Text -> Text
forall appendable.
Semigroup appendable =>
appendable -> appendable -> appendable
++ String -> Text
Data.Text.pack (FloatingPointTolerance -> String
forall a. Show a => a -> String
Prelude.show FloatingPointTolerance
tolerance))
withinHelper :: FloatingPointTolerance -> Float -> Float -> Bool
withinHelper :: FloatingPointTolerance -> Float -> Float -> Bool
withinHelper FloatingPointTolerance
tolerance Float
expected Float
actual =
case FloatingPointTolerance
tolerance of
Absolute Float
absTolerance -> Float -> Float
forall number. Num number => number -> number
abs (Float
actual Float -> Float -> Float
forall number. Num number => number -> number -> number
- Float
expected) Float -> Float -> Bool
forall comparable.
Ord comparable =>
comparable -> comparable -> Bool
<= Float
absTolerance
Relative Float
relTolerance -> Float -> Float
forall number. Num number => number -> number
abs (Float
actual Float -> Float -> Float
forall number. Num number => number -> number -> number
- Float
expected) Float -> Float -> Float
/ Float
expected Float -> Float -> Bool
forall comparable.
Ord comparable =>
comparable -> comparable -> Bool
<= Float
relTolerance
AbsoluteOrRelative Float
absTolerance Float
relTolerance ->
FloatingPointTolerance -> Float -> Float -> Bool
withinHelper (Float -> FloatingPointTolerance
Absolute Float
absTolerance) Float
expected Float
actual
Bool -> Bool -> Bool
|| FloatingPointTolerance -> Float -> Float -> Bool
withinHelper (Float -> FloatingPointTolerance
Relative Float
relTolerance) Float
expected Float
actual
true :: Stack.HasCallStack => Bool -> Expectation
true :: Bool -> Expectation
true Bool
x =
if Bool
x
then (HasCallStack => Text -> () -> Expectation)
-> Text -> () -> Expectation
forall a. HasCallStack => (HasCallStack => a) -> a
Stack.withFrozenCallStack HasCallStack => Text -> () -> Expectation
forall a. HasCallStack => Text -> a -> Expectation' a
Internal.pass Text
"Expect.true" ()
else (HasCallStack => Text -> Text -> Expectation)
-> Text -> Text -> Expectation
forall a. HasCallStack => (HasCallStack => a) -> a
Stack.withFrozenCallStack HasCallStack => Text -> Text -> Expectation
forall a. HasCallStack => Text -> Text -> Expectation' a
Internal.failAssertion Text
"Expect.true" Text
"I expected a True but got False"
false :: Stack.HasCallStack => Bool -> Expectation
false :: Bool -> Expectation
false Bool
x =
if Bool
x
then (HasCallStack => Text -> Text -> Expectation)
-> Text -> Text -> Expectation
forall a. HasCallStack => (HasCallStack => a) -> a
Stack.withFrozenCallStack HasCallStack => Text -> Text -> Expectation
forall a. HasCallStack => Text -> Text -> Expectation' a
Internal.failAssertion Text
"Expect.false" Text
"I expected a False but got True"
else (HasCallStack => Text -> () -> Expectation)
-> Text -> () -> Expectation
forall a. HasCallStack => (HasCallStack => a) -> a
Stack.withFrozenCallStack HasCallStack => Text -> () -> Expectation
forall a. HasCallStack => Text -> a -> Expectation' a
Internal.pass Text
"Expect.false" ()
all :: Stack.HasCallStack => List (subject -> Expectation) -> subject -> Expectation
all :: List (subject -> Expectation) -> subject -> Expectation
all List (subject -> Expectation)
expectations subject
subject =
((subject -> Expectation) -> Expectation -> Expectation)
-> Expectation -> List (subject -> Expectation) -> Expectation
forall a b. (a -> b -> b) -> b -> List a -> b
List.foldl
( \subject -> Expectation
expectation Expectation
acc ->
Expectation -> Expectation -> Expectation
Internal.append
Expectation
acc
((HasCallStack => subject -> Expectation) -> subject -> Expectation
forall a. HasCallStack => (HasCallStack => a) -> a
Stack.withFrozenCallStack subject -> Expectation
HasCallStack => subject -> Expectation
expectation subject
subject)
)
Expectation
HasCallStack => Expectation
pass
List (subject -> Expectation)
expectations
ok :: (Stack.HasCallStack, Show b) => Result b a -> Expectation
ok :: Result b a -> Expectation
ok Result b a
res =
case Result b a
res of
Ok a
_ ->
(HasCallStack => Text -> () -> Expectation)
-> Text -> () -> Expectation
forall a. HasCallStack => (HasCallStack => a) -> a
Stack.withFrozenCallStack
HasCallStack => Text -> () -> Expectation
forall a. HasCallStack => Text -> a -> Expectation' a
Internal.pass
Text
"Expect.ok"
()
Err b
message ->
(HasCallStack => Text -> Text -> Expectation)
-> Text -> Text -> Expectation
forall a. HasCallStack => (HasCallStack => a) -> a
Stack.withFrozenCallStack
HasCallStack => Text -> Text -> Expectation
forall a. HasCallStack => Text -> Text -> Expectation' a
Internal.failAssertion
Text
"Expect.ok"
(Text
"I expected a Ok but got Err (" Text -> Text -> Text
forall appendable.
Semigroup appendable =>
appendable -> appendable -> appendable
++ b -> Text
forall a. Show a => a -> Text
Debug.toString b
message Text -> Text -> Text
forall appendable.
Semigroup appendable =>
appendable -> appendable -> appendable
++ Text
")")
err :: (Stack.HasCallStack, Show a) => Result b a -> Expectation
err :: Result b a -> Expectation
err Result b a
res =
case Result b a
res of
Ok a
value ->
(HasCallStack => Text -> Text -> Expectation)
-> Text -> Text -> Expectation
forall a. HasCallStack => (HasCallStack => a) -> a
Stack.withFrozenCallStack
HasCallStack => Text -> Text -> Expectation
forall a. HasCallStack => Text -> Text -> Expectation' a
Internal.failAssertion
Text
"Expect.err"
(Text
"I expected a Err but got Ok (" Text -> Text -> Text
forall appendable.
Semigroup appendable =>
appendable -> appendable -> appendable
++ a -> Text
forall a. Show a => a -> Text
Debug.toString a
value Text -> Text -> Text
forall appendable.
Semigroup appendable =>
appendable -> appendable -> appendable
++ Text
")")
Err b
_ ->
(HasCallStack => Text -> () -> Expectation)
-> Text -> () -> Expectation
forall a. HasCallStack => (HasCallStack => a) -> a
Stack.withFrozenCallStack
HasCallStack => Text -> () -> Expectation
forall a. HasCallStack => Text -> a -> Expectation' a
Internal.pass
Text
"Expect.err"
()
equalToContentsOf :: Stack.HasCallStack => Text -> Text -> Expectation
equalToContentsOf :: Text -> Text -> Expectation
equalToContentsOf Text
filepath' Text
actual = do
let filepath :: String
filepath = Text -> String
Data.Text.unpack Text
filepath'
Bool
exists <-
IO Bool -> Expectation' Bool
forall a. IO a -> Expectation' a
fromIO (IO Bool -> Expectation' Bool) -> IO Bool -> Expectation' Bool
forall a b. (a -> b) -> a -> b
<| do
Bool -> String -> IO ()
Directory.createDirectoryIfMissing Bool
True (ShowS
FilePath.takeDirectory String
filepath)
String -> IO Bool
Directory.doesFileExist String
filepath
if Bool
exists
then do
Text
expected <- IO Text -> Expectation' Text
forall a. IO a -> Expectation' a
fromIO (String -> IO Text
Data.Text.IO.readFile String
filepath)
(HasCallStack =>
(UnescapedShow -> UnescapedShow -> Bool)
-> Text -> UnescapedShow -> UnescapedShow -> Expectation)
-> (UnescapedShow -> UnescapedShow -> Bool)
-> Text
-> UnescapedShow
-> UnescapedShow
-> Expectation
forall a. HasCallStack => (HasCallStack => a) -> a
Stack.withFrozenCallStack
HasCallStack =>
(UnescapedShow -> UnescapedShow -> Bool)
-> Text -> UnescapedShow -> UnescapedShow -> Expectation
forall a.
(HasCallStack, Show a) =>
(a -> a -> Bool) -> Text -> a -> a -> Expectation
assert
UnescapedShow -> UnescapedShow -> Bool
forall a. Eq a => a -> a -> Bool
(==)
(Text
"Expect.equalToContentsOf " Text -> Text -> Text
forall appendable.
Semigroup appendable =>
appendable -> appendable -> appendable
++ Text
filepath')
(Text -> UnescapedShow
UnescapedShow Text
expected)
(Text -> UnescapedShow
UnescapedShow Text
actual)
else do
IO () -> Expectation
forall a. IO a -> Expectation' a
fromIO (String -> Text -> IO ()
Data.Text.IO.writeFile String
filepath Text
actual)
(HasCallStack => Text -> () -> Expectation)
-> Text -> () -> Expectation
forall a. HasCallStack => (HasCallStack => a) -> a
Stack.withFrozenCallStack
HasCallStack => Text -> () -> Expectation
forall a. HasCallStack => Text -> a -> Expectation' a
Internal.pass
(Text
"Expect.equalToContentsOf " Text -> Text -> Text
forall appendable.
Semigroup appendable =>
appendable -> appendable -> appendable
++ Text
filepath')
()
newtype UnescapedShow = UnescapedShow Text deriving (UnescapedShow -> UnescapedShow -> Bool
(UnescapedShow -> UnescapedShow -> Bool)
-> (UnescapedShow -> UnescapedShow -> Bool) -> Eq UnescapedShow
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: UnescapedShow -> UnescapedShow -> Bool
$c/= :: UnescapedShow -> UnescapedShow -> Bool
== :: UnescapedShow -> UnescapedShow -> Bool
$c== :: UnescapedShow -> UnescapedShow -> Bool
Eq)
instance Show UnescapedShow where
show :: UnescapedShow -> String
show (UnescapedShow Text
text) = Text -> String
Data.Text.unpack Text
text
assert :: (Stack.HasCallStack, Show a) => (a -> a -> Bool) -> Text -> a -> a -> Expectation
assert :: (a -> a -> Bool) -> Text -> a -> a -> Expectation
assert a -> a -> Bool
pred Text
funcName a
expected a
actual =
if a -> a -> Bool
pred a
expected a
actual
then (HasCallStack => Text -> () -> Expectation)
-> Text -> () -> Expectation
forall a. HasCallStack => (HasCallStack => a) -> a
Stack.withFrozenCallStack HasCallStack => Text -> () -> Expectation
forall a. HasCallStack => Text -> a -> Expectation' a
Internal.pass Text
funcName ()
else do
Maybe (Window Int)
window <- IO (Maybe (Window Int)) -> Expectation' (Maybe (Window Int))
forall a. IO a -> Expectation' a
fromIO IO (Maybe (Window Int))
forall n. Integral n => IO (Maybe (Window n))
Terminal.size
let terminalWidth :: Int
terminalWidth = case Maybe (Window Int)
window of
Just Terminal.Window {Int
width :: forall a. Window a -> a
width :: Int
Terminal.width} -> Int
width Int -> Int -> Int
forall number. Num number => number -> number -> number
- Int
4
Maybe (Window Int)
Nothing -> Int
80
let expectedText :: Text
expectedText = String -> Text
Data.Text.pack (a -> String
forall a. Show a => a -> String
Text.Show.Pretty.ppShow a
actual)
let actualText :: Text
actualText = String -> Text
Data.Text.pack (a -> String
forall a. Show a => a -> String
Text.Show.Pretty.ppShow a
expected)
let numLines :: Text -> Int
numLines Text
text = List Text -> Int
forall a. List a -> Int
List.length (Text -> List Text
Data.Text.lines Text
text)
(HasCallStack => Text -> Text -> Expectation)
-> Text -> Text -> Expectation
forall a. HasCallStack => (HasCallStack => a) -> a
Stack.withFrozenCallStack HasCallStack => Text -> Text -> Expectation
forall a. HasCallStack => Text -> Text -> Expectation' a
Internal.failAssertion Text
funcName
(Text -> Expectation) -> Text -> Expectation
forall a b. (a -> b) -> a -> b
<| Config -> Text -> Text -> Text
Diff.pretty
Config :: Maybe Text -> Wrapping -> MultilineContext -> Config
Diff.Config
{ separatorText :: Maybe Text
Diff.separatorText = Text -> Maybe Text
forall a. a -> Maybe a
Just Text
funcName,
wrapping :: Wrapping
Diff.wrapping = Int -> Wrapping
Diff.Wrap Int
terminalWidth,
multilineContext :: MultilineContext
Diff.multilineContext =
if Text -> Int
numLines Text
expectedText Int -> Int -> Bool
forall comparable.
Ord comparable =>
comparable -> comparable -> Bool
< Int
6 Bool -> Bool -> Bool
&& Text -> Int
numLines Text
actualText Int -> Int -> Bool
forall comparable.
Ord comparable =>
comparable -> comparable -> Bool
< Int
6
then MultilineContext
Diff.FullContext
else Int -> Text -> MultilineContext
Diff.Surrounding Int
2 Text
"..."
}
Text
expectedText
Text
actualText
fromIO :: Prelude.IO a -> Internal.Expectation' a
fromIO :: IO a -> Expectation' a
fromIO IO a
io =
(LogHandler -> IO (Result Failure a)) -> Task Failure a
forall x a. (LogHandler -> IO (Result x a)) -> Task x a
Platform.Internal.Task (\LogHandler
_ -> (a -> Result Failure a) -> IO a -> IO (Result Failure a)
forall (m :: * -> *) a value.
Functor m =>
(a -> value) -> m a -> m value
map a -> Result Failure a
forall error value. value -> Result error value
Ok IO a
io)
Task Failure a
-> (Task Failure a -> Expectation' a) -> Expectation' a
forall a b. a -> (a -> b) -> b
|> Task Failure a -> Expectation' a
forall a. Task Failure a -> Expectation' a
Internal.Expectation
fromResult :: (Stack.HasCallStack, Show b) => Result b a -> Internal.Expectation' a
fromResult :: Result b a -> Expectation' a
fromResult (Ok a
a) =
(HasCallStack => Text -> a -> Expectation' a)
-> Text -> a -> Expectation' a
forall a. HasCallStack => (HasCallStack => a) -> a
Stack.withFrozenCallStack
HasCallStack => Text -> a -> Expectation' a
forall a. HasCallStack => Text -> a -> Expectation' a
Internal.pass
Text
"Expect.fromResult"
a
a
fromResult (Err b
msg) =
(HasCallStack => Text -> Text -> Expectation' a)
-> Text -> Text -> Expectation' a
forall a. HasCallStack => (HasCallStack => a) -> a
Stack.withFrozenCallStack
HasCallStack => Text -> Text -> Expectation' a
forall a. HasCallStack => Text -> Text -> Expectation' a
Internal.failAssertion
Text
"Expect.fromResult"
(b -> Text
forall a. Show a => a -> Text
Debug.toString b
msg)
andCheck :: (Stack.HasCallStack, Show err) => (a -> Expectation) -> Task err a -> Internal.Expectation
andCheck :: (a -> Expectation) -> Task err a -> Expectation
andCheck a -> Expectation
expectation Task err a
task = do
a
x <- Task err a -> Expectation' a
forall err a.
(HasCallStack, Show err) =>
Task err a -> Expectation' a
succeeds Task err a
task
(HasCallStack => a -> Expectation) -> a -> Expectation
forall a. HasCallStack => (HasCallStack => a) -> a
Stack.withFrozenCallStack a -> Expectation
HasCallStack => a -> Expectation
expectation a
x
succeeds :: (Stack.HasCallStack, Show err) => Task err a -> Internal.Expectation' a
succeeds :: Task err a -> Expectation' a
succeeds Task err a
task =
Task err a
task
Task err a -> (Task err a -> Task Failure a) -> Task Failure a
forall a b. a -> (a -> b) -> b
|> (err -> Task Failure a) -> Task err a -> Task Failure a
forall x y a. (x -> Task y a) -> Task x a -> Task y a
Task.onError
( \err
message ->
(HasCallStack => Text -> Text -> Expectation' a)
-> Text -> Text -> Expectation' a
forall a. HasCallStack => (HasCallStack => a) -> a
Stack.withFrozenCallStack
HasCallStack => Text -> Text -> Expectation' a
forall a. HasCallStack => Text -> Text -> Expectation' a
Internal.failAssertion
Text
"Expect.succeeds"
(err -> Text
forall a. Show a => a -> Text
Debug.toString err
message)
Expectation' a
-> (Expectation' a -> Task Failure a) -> Task Failure a
forall a b. a -> (a -> b) -> b
|> Expectation' a -> Task Failure a
forall a. Expectation' a -> Task Failure a
Internal.unExpectation
)
Task Failure a
-> (Task Failure a -> Task Failure a) -> Task Failure a
forall a b. a -> (a -> b) -> b
|> (a -> Task Failure a) -> Task Failure a -> Task Failure a
forall a x b. (a -> Task x b) -> Task x a -> Task x b
Task.andThen
( \a
a ->
(HasCallStack => Text -> a -> Expectation' a)
-> Text -> a -> Expectation' a
forall a. HasCallStack => (HasCallStack => a) -> a
Stack.withFrozenCallStack
HasCallStack => Text -> a -> Expectation' a
forall a. HasCallStack => Text -> a -> Expectation' a
Internal.pass
Text
"Expect.succeeds"
a
a
Expectation' a
-> (Expectation' a -> Task Failure a) -> Task Failure a
forall a b. a -> (a -> b) -> b
|> Expectation' a -> Task Failure a
forall a. Expectation' a -> Task Failure a
Internal.unExpectation
)
Task Failure a
-> (Task Failure a -> Expectation' a) -> Expectation' a
forall a b. a -> (a -> b) -> b
|> Task Failure a -> Expectation' a
forall a. Task Failure a -> Expectation' a
Internal.Expectation
fails :: (Stack.HasCallStack, Show a) => Task err a -> Internal.Expectation' err
fails :: Task err a -> Expectation' err
fails Task err a
task =
Task err a
task
Task err a
-> (Task err a -> Task err (Result Text err))
-> Task err (Result Text err)
forall a b. a -> (a -> b) -> b
|> (a -> Result Text err) -> Task err a -> Task err (Result Text err)
forall a b x. (a -> b) -> Task x a -> Task x b
Task.map (\a
succ -> Text -> Result Text err
forall error value. error -> Result error value
Err (Text
"Expected failure but succeeded with " Text -> Text -> Text
forall appendable.
Semigroup appendable =>
appendable -> appendable -> appendable
++ a -> Text
forall a. Show a => a -> Text
Debug.toString a
succ))
Task err (Result Text err)
-> (Task err (Result Text err) -> Task Failure (Result Text err))
-> Task Failure (Result Text err)
forall a b. a -> (a -> b) -> b
|> (err -> Task Failure (Result Text err))
-> Task err (Result Text err) -> Task Failure (Result Text err)
forall x y a. (x -> Task y a) -> Task x a -> Task y a
Task.onError (\err
err' -> Result Text err -> Task Failure (Result Text err)
forall a x. a -> Task x a
Task.succeed (err -> Result Text err
forall error value. value -> Result error value
Ok err
err'))
Task Failure (Result Text err)
-> (Task Failure (Result Text err) -> Task Failure err)
-> Task Failure err
forall a b. a -> (a -> b) -> b
|> (Result Text err -> Task Failure err)
-> Task Failure (Result Text err) -> Task Failure err
forall a x b. (a -> Task x b) -> Task x a -> Task x b
Task.andThen
( \Result Text err
res ->
Expectation' err -> Task Failure err
forall a. Expectation' a -> Task Failure a
Internal.unExpectation
(Expectation' err -> Task Failure err)
-> Expectation' err -> Task Failure err
forall a b. (a -> b) -> a -> b
<| case Result Text err
res of
Ok err
a ->
(HasCallStack => Text -> err -> Expectation' err)
-> Text -> err -> Expectation' err
forall a. HasCallStack => (HasCallStack => a) -> a
Stack.withFrozenCallStack
HasCallStack => Text -> err -> Expectation' err
forall a. HasCallStack => Text -> a -> Expectation' a
Internal.pass
Text
"Expect.fails"
err
a
Err Text
msg ->
(HasCallStack => Text -> Text -> Expectation' err)
-> Text -> Text -> Expectation' err
forall a. HasCallStack => (HasCallStack => a) -> a
Stack.withFrozenCallStack
HasCallStack => Text -> Text -> Expectation' err
forall a. HasCallStack => Text -> Text -> Expectation' a
Internal.failAssertion
Text
"Expect.fails"
(Text -> Text
forall a. Show a => a -> Text
Debug.toString Text
msg)
)
Task Failure err
-> (Task Failure err -> Expectation' err) -> Expectation' err
forall a b. a -> (a -> b) -> b
|> Task Failure err -> Expectation' err
forall a. Task Failure a -> Expectation' a
Internal.Expectation
around ::
(forall e a. (arg -> Task e a) -> Task e a) ->
(arg -> Expectation) ->
Expectation
around :: (forall e a. (arg -> Task e a) -> Task e a)
-> (arg -> Expectation) -> Expectation
around forall e a. (arg -> Task e a) -> Task e a
runTask arg -> Expectation
runExpectation =
Task Failure () -> Expectation
forall a. Task Failure a -> Expectation' a
Internal.Expectation
( (arg -> Task Failure ()) -> Task Failure ()
forall e a. (arg -> Task e a) -> Task e a
runTask
( \arg
arg ->
arg -> Expectation
runExpectation arg
arg
Expectation -> (Expectation -> Task Failure ()) -> Task Failure ()
forall a b. a -> (a -> b) -> b
|> Expectation -> Task Failure ()
forall a. Expectation' a -> Task Failure a
Internal.unExpectation
)
)