3 | import public Decidable.Equality
4 | import public Evince.SrcLoc
9 | data FailureInfo : Type where
10 | ExpectedButGot : (reason : String) -> (expected : String) -> (actual : String) -> FailureInfo
11 | PredicateFailed : (reason : String) -> (actual : String) -> FailureInfo
12 | Reason : (message : String) -> FailureInfo
15 | Show FailureInfo where
16 | show (ExpectedButGot reason expected actual) =
17 | reason ++ "\nexpected: " ++ expected ++ "\n actual: " ++ actual
18 | show (PredicateFailed reason actual) =
19 | reason ++ "\n value: " ++ actual
20 | show (Reason message) = message
23 | DecEq FailureInfo where
24 | decEq (ExpectedButGot r1 e1 a1) (ExpectedButGot r2 e2 a2) =
25 | case (decEq r1 r2, decEq e1 e2, decEq a1 a2) of
26 | (Yes Refl, Yes Refl, Yes Refl) => Yes Refl
27 | (No c, _, _) => No $
\case Refl => c Refl
28 | (_, No c, _) => No $
\case Refl => c Refl
29 | (_, _, No c) => No $
\case Refl => c Refl
30 | decEq (PredicateFailed r1 a1) (PredicateFailed r2 a2) =
31 | case (decEq r1 r2, decEq a1 a2) of
32 | (Yes Refl, Yes Refl) => Yes Refl
33 | (No c, _) => No $
\case Refl => c Refl
34 | (_, No c) => No $
\case Refl => c Refl
35 | decEq (Reason m1) (Reason m2) = case decEq m1 m2 of
36 | Yes Refl => Yes Refl
37 | No c => No $
\case Refl => c Refl
38 | decEq (ExpectedButGot _ _ _) (PredicateFailed _ _) = No $
\case Refl
impossible
39 | decEq (ExpectedButGot _ _ _) (Reason _) = No $
\case Refl
impossible
40 | decEq (PredicateFailed _ _) (ExpectedButGot _ _ _) = No $
\case Refl
impossible
41 | decEq (PredicateFailed _ _) (Reason _) = No $
\case Refl
impossible
42 | decEq (Reason _) (ExpectedButGot _ _ _) = No $
\case Refl
impossible
43 | decEq (Reason _) (PredicateFailed _ _) = No $
\case Refl
impossible
48 | data TestResult : Type -> Type where
49 | Pass : a -> TestResult a
50 | Fail : FailureInfo -> TestResult a
51 | Skip : (reason : Maybe String) -> TestResult a
54 | Show a => Show (TestResult a) where
55 | show (Pass x) = "Pass " ++ show x
56 | show (Fail info) = "Fail (" ++ show info ++ ")"
57 | show (Skip reason) = "Skip " ++ show reason
60 | DecEq a => DecEq (TestResult a) where
61 | decEq (Pass x) (Pass y) = case decEq x y of
62 | Yes Refl => Yes Refl
63 | No c => No $
\case Refl => c Refl
64 | decEq (Fail i1) (Fail i2) = case decEq i1 i2 of
65 | Yes Refl => Yes Refl
66 | No c => No $
\case Refl => c Refl
67 | decEq (Skip r1) (Skip r2) = case decEq r1 r2 of
68 | Yes Refl => Yes Refl
69 | No c => No $
\case Refl => c Refl
70 | decEq (Pass _) (Fail _) = No $
\case Refl
impossible
71 | decEq (Pass _) (Skip _) = No $
\case Refl
impossible
72 | decEq (Fail _) (Pass _) = No $
\case Refl
impossible
73 | decEq (Fail _) (Skip _) = No $
\case Refl
impossible
74 | decEq (Skip _) (Pass _) = No $
\case Refl
impossible
75 | decEq (Skip _) (Fail _) = No $
\case Refl
impossible
78 | Functor TestResult where
79 | map f (Pass x) = Pass (f x)
80 | map f (Fail info) = Fail info
81 | map f (Skip reason) = Skip reason
84 | Applicative TestResult where
86 | (Pass f) <*> x = map f x
87 | (Fail info) <*> _ = Fail info
88 | (Skip reason) <*> _ = Skip reason
91 | Monad TestResult where
92 | (Pass x) >>= f = f x
93 | (Fail info) >>= _ = Fail info
94 | (Skip reason) >>= _ = Skip reason
98 | data SpecTree : (m : Type -> Type) -> Type -> Type where
99 | Describe : (label : String) -> (children : List (SpecTree m a)) -> SpecTree m a
100 | It : (label : String) -> (loc : Maybe SrcLoc) -> (test : a -> m (TestResult ())) -> SpecTree m a
101 | Pending : (label : String) -> (reason : Maybe String) -> SpecTree m a
102 | Focused : SpecTree m a -> SpecTree m a
103 | WithCleanup : (cleanup : m ()) -> (children : List (SpecTree m a)) -> SpecTree m a
109 | data Spec : (m : Type -> Type) -> Type -> Type -> Type where
110 | MkSpec : SnocList (SpecTree m a) -> b -> Spec m a b
113 | Functor (Spec m a) where
114 | map f (MkSpec trees x) = MkSpec trees (f x)
117 | Applicative (Spec m a) where
118 | pure x = MkSpec [<] x
119 | (MkSpec ts1 f) <*> (MkSpec ts2 x) = MkSpec (ts1 ++ ts2) (f x)
122 | Monad (Spec m a) where
123 | (MkSpec ts1 x) >>= f = let (MkSpec ts2 y) = f x in MkSpec (ts1 ++ ts2) y
127 | getSpecTrees : Spec m a () -> List (SpecTree m a)
128 | getSpecTrees (MkSpec trees ()) = trees <>> []
131 | record Summary where
132 | constructor MkSummary
139 | Semigroup Summary where
140 | (MkSummary p1 f1 pn1 d1) <+> (MkSummary p2 f2 pn2 d2) =
141 | MkSummary (p1 + p2) (f1 + f2) (pn1 + pn2) (d1 + d2)
144 | Monoid Summary where
145 | neutral = MkSummary 0 0 0 0
149 | show s = show s.passed ++ " passing, "
150 | ++ show s.failed ++ " failing, "
151 | ++ show s.pending ++ " pending"
154 | totalCount : Summary -> Nat
155 | totalCount s = s.passed + s.failed + s.pending
158 | record RunConfig where
159 | constructor MkRunConfig
162 | match : Maybe String
163 | skip : Maybe String
166 | junitOutput : Maybe String
173 | defaultConfig : RunConfig
174 | defaultConfig = MkRunConfig False False Nothing Nothing False Nothing Nothing False 0 True