{-# LANGUAGE GADTs #-}
{-# LANGUAGE RankNTypes #-}
module Expect
(
Expectation,
equal,
notEqual,
all,
equalToContentsOf,
equalH,
FloatingPointTolerance (..),
within,
notWithin,
lessThan,
atMost,
greaterThan,
atLeast,
true,
false,
ok,
err,
pass,
fail,
onFail,
fromResult,
succeeds,
fails,
andCheck,
Internal.fromIO,
Internal.runExpectation,
Internal.fromIOResult,
Internal.Expectation',
Internal.Failure,
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 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 Type.Reflection (Typeable, eqTypeRep, typeOf, (:~~:) (HRefl))
import qualified Prelude
pass :: (Stack.HasCallStack) => Expectation
pass :: HasCallStack => Expectation
pass = (HasCallStack => Text -> () -> Expectation)
-> Text -> () -> Expectation
forall a. HasCallStack => (HasCallStack => a) -> a
Stack.withFrozenCallStack HasCallStack => Text -> () -> Expectation
Text -> () -> Expectation
forall a. HasCallStack => Text -> a -> Expectation' a
Internal.pass Text
"Expect.pass" ()
fail :: (Stack.HasCallStack) => Text -> Expectation
fail :: HasCallStack => Text -> Expectation
fail Text
msg =
(HasCallStack => Text -> Text -> Expectation)
-> Text -> Text -> Expectation
forall a. HasCallStack => (HasCallStack => a) -> a
Stack.withFrozenCallStack HasCallStack => Text -> Text -> Expectation
Text -> Text -> Expectation
forall a. HasCallStack => Text -> Text -> Expectation' a
Internal.failAssertion Text
"Expect.fail" Text
msg
onFail :: (Stack.HasCallStack) => Text -> Expectation -> Expectation
onFail :: HasCallStack => 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
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 :: forall a. (HasCallStack, Show a, Eq a) => 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
(a -> a -> Bool) -> Text -> a -> a -> Expectation
forall a b.
(HasCallStack, Show a, Show b) =>
(a -> b -> Bool) -> Text -> a -> b -> Expectation
assert a -> a -> Bool
forall a. Eq a => a -> a -> Bool
(==) Text
"Expect.equal"
equalH :: (Stack.HasCallStack, Show a, Show b, Eq a, Typeable a, Typeable b) => a -> b -> Expectation
equalH :: forall a b.
(HasCallStack, Show a, Show b, Eq a, Typeable a, Typeable b) =>
a -> b -> Expectation
equalH = (HasCallStack => (a -> b -> Bool) -> Text -> a -> b -> Expectation)
-> (a -> b -> Bool) -> Text -> a -> b -> Expectation
forall a. HasCallStack => (HasCallStack => a) -> a
Stack.withFrozenCallStack HasCallStack => (a -> b -> Bool) -> Text -> a -> b -> Expectation
(a -> b -> Bool) -> Text -> a -> b -> Expectation
forall a b.
(HasCallStack, Show a, Show b) =>
(a -> b -> Bool) -> Text -> a -> b -> Expectation
assert a -> b -> Bool
forall a b. (Eq a, Typeable a, Typeable b) => a -> b -> Bool
equalHPredicate Text
"Expect.equalH"
equalHPredicate :: (Eq a, Typeable a, Typeable b) => a -> b -> Bool
equalHPredicate :: forall a b. (Eq a, Typeable a, Typeable b) => a -> b -> Bool
equalHPredicate a
x b
y =
case TypeRep a -> TypeRep b -> Maybe (a :~~: b)
forall k1 k2 (a :: k1) (b :: k2).
TypeRep a -> TypeRep b -> Maybe (a :~~: b)
eqTypeRep (a -> TypeRep a
forall a. Typeable a => a -> TypeRep a
typeOf a
x) (b -> TypeRep b
forall a. Typeable a => a -> TypeRep a
typeOf b
y) of
Maybe (a :~~: b)
Nothing -> Bool
False
Just a :~~: b
HRefl -> a
x a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
b
y
notEqual :: (Stack.HasCallStack, Show a, Eq a) => a -> a -> Expectation
notEqual :: forall a. (HasCallStack, Show a, Eq a) => 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
(a -> a -> Bool) -> Text -> a -> a -> Expectation
forall a b.
(HasCallStack, Show a, Show b) =>
(a -> b -> Bool) -> Text -> a -> b -> 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 :: forall a. (HasCallStack, Show a, Ord a) => 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
(a -> a -> Bool) -> Text -> a -> a -> Expectation
forall a b.
(HasCallStack, Show a, Show b) =>
(a -> b -> Bool) -> Text -> a -> b -> 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 :: forall a. (HasCallStack, Show a, Ord a) => 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
(a -> a -> Bool) -> Text -> a -> a -> Expectation
forall a b.
(HasCallStack, Show a, Show b) =>
(a -> b -> Bool) -> Text -> a -> b -> 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 :: forall a. (HasCallStack, Show a, Ord a) => 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
(a -> a -> Bool) -> Text -> a -> a -> Expectation
forall a b.
(HasCallStack, Show a, Show b) =>
(a -> b -> Bool) -> Text -> a -> b -> 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 :: forall a. (HasCallStack, Show a, Ord a) => 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
(a -> a -> Bool) -> Text -> a -> a -> Expectation
forall a b.
(HasCallStack, Show a, Show b) =>
(a -> b -> Bool) -> Text -> a -> b -> 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
$cshowsPrec :: Int -> FloatingPointTolerance -> ShowS
showsPrec :: Int -> FloatingPointTolerance -> ShowS
$cshow :: FloatingPointTolerance -> String
show :: FloatingPointTolerance -> String
$cshowList :: [FloatingPointTolerance] -> ShowS
showList :: [FloatingPointTolerance] -> ShowS
Show)
within :: (Stack.HasCallStack) => FloatingPointTolerance -> Float -> Float -> Expectation
within :: HasCallStack =>
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
(Float -> Float -> Bool) -> Text -> Float -> Float -> Expectation
forall a b.
(HasCallStack, Show a, Show b) =>
(a -> b -> Bool) -> Text -> a -> b -> 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 :: HasCallStack =>
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
(Float -> Float -> Bool) -> Text -> Float -> Float -> Expectation
forall a b.
(HasCallStack, Show a, Show b) =>
(a -> b -> Bool) -> Text -> a -> b -> 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 :: HasCallStack => 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
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
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 :: HasCallStack => 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
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
Text -> () -> Expectation
forall a. HasCallStack => Text -> a -> Expectation' a
Internal.pass Text
"Expect.false" ()
all :: (Stack.HasCallStack) => List (subject -> Expectation) -> subject -> Expectation
all :: forall subject.
HasCallStack =>
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 :: forall b a. (HasCallStack, Show b) => 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
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
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 :: forall a b. (HasCallStack, Show a) => 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
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
Text -> () -> Expectation
forall a. HasCallStack => Text -> a -> Expectation' a
Internal.pass
Text
"Expect.err"
()
equalToContentsOf :: (Stack.HasCallStack) => Text -> Text -> Expectation
equalToContentsOf :: HasCallStack => Text -> Text -> Expectation
equalToContentsOf Text
filepath' Text
actual = do
let filepath :: String
filepath = Text -> String
Data.Text.unpack Text
filepath'
exists <-
IO Bool -> Expectation' Bool
forall a. IO a -> Expectation' a
Internal.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 exists
then do
expected <- Internal.fromIO (Data.Text.IO.readFile filepath)
Stack.withFrozenCallStack
assert
(==)
("Expect.equalToContentsOf " ++ filepath')
(UnescapedShow expected)
(UnescapedShow actual)
else do
Internal.fromIO (Data.Text.IO.writeFile filepath actual)
Stack.withFrozenCallStack
Internal.pass
("Expect.equalToContentsOf " ++ 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
$c== :: UnescapedShow -> UnescapedShow -> Bool
== :: UnescapedShow -> UnescapedShow -> Bool
$c/= :: UnescapedShow -> UnescapedShow -> Bool
/= :: 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, Show b) => (a -> b -> Bool) -> Text -> a -> b -> Expectation
assert :: forall a b.
(HasCallStack, Show a, Show b) =>
(a -> b -> Bool) -> Text -> a -> b -> Expectation
assert a -> b -> Bool
pred Text
funcName a
expected b
actual =
if a -> b -> Bool
pred a
expected b
actual
then (HasCallStack => Text -> () -> Expectation)
-> Text -> () -> Expectation
forall a. HasCallStack => (HasCallStack => a) -> a
Stack.withFrozenCallStack HasCallStack => Text -> () -> Expectation
Text -> () -> Expectation
forall a. HasCallStack => Text -> a -> Expectation' a
Internal.pass Text
funcName ()
else do
window <- IO (Maybe (Window Int)) -> Expectation' (Maybe (Window Int))
forall a. IO a -> Expectation' a
Internal.fromIO IO (Maybe (Window Int))
forall n. Integral n => IO (Maybe (Window n))
Terminal.size
let terminalWidth = case Maybe (Window Int)
window of
Just Terminal.Window {Int
width :: Int
width :: forall a. Window a -> a
Terminal.width} -> Int
width Int -> Int -> Int
forall number. Num number => number -> number -> number
- Int
4
Maybe (Window Int)
Nothing -> Int
80
let expectedText = String -> Text
Data.Text.pack (b -> String
forall a. Show a => a -> String
Text.Show.Pretty.ppShow b
actual)
let actualText = String -> Text
Data.Text.pack (a -> String
forall a. Show a => a -> String
Text.Show.Pretty.ppShow a
expected)
let numLines Text
text = List Text -> Int
forall a. List a -> Int
List.length (Text -> List Text
Data.Text.lines Text
text)
Stack.withFrozenCallStack Internal.failAssertion funcName <|
Diff.pretty
Diff.Config
{ Diff.separatorText = Just funcName,
Diff.wrapping = Diff.Wrap terminalWidth,
Diff.multilineContext =
if numLines expectedText < 6 && numLines actualText < 6
then Diff.FullContext
else Diff.Surrounding 2 "..."
}
expectedText
actualText
fromResult :: (Stack.HasCallStack, Show b) => Result b a -> Internal.Expectation' a
fromResult :: forall b a. (HasCallStack, Show b) => 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
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
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 :: forall err a.
(HasCallStack, Show err) =>
(a -> Expectation) -> Task err a -> Expectation
andCheck a -> Expectation
expectation Task err a
task = do
x <- Task err a -> Expectation' a
forall err a.
(HasCallStack, Show err) =>
Task err a -> Expectation' a
succeeds Task err a
task
Stack.withFrozenCallStack expectation x
succeeds :: (Stack.HasCallStack, Show err) => Task err a -> Internal.Expectation' a
succeeds :: forall err a.
(HasCallStack, Show err) =>
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
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
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 :: forall a err.
(HasCallStack, Show a) =>
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
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
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 arg.
(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
)
)