import StdOverloaded, StdBool, StdString, StdEnum, StdList\r
\r
:: TestState = {s :: Int, f :: Int, p :: [String]}\r
-:: Test :== (TestState -> TestState)\r
-:: Match a \r
- = Is (Match a)\r
- | Not (Match a)\r
- | Either (Match a) (Match a)\r
- | LessThen a\r
- | EqualTo a\r
-\r
-eval :: a (Match a) -> Bool | ==, < a\r
-eval x (Is y) = eval x y\r
-eval x (EqualTo y) = x == y\r
-eval x (LessThen y) = x < y\r
-eval x (Not y) = not (eval x y)\r
-eval x (Either y1 y2) = eval x y1 || eval x y2\r
-\r
-show :: (Match a) [String] -> [String] | toString a\r
-show (Is x) l = ["(Is ":show x [")":l]]\r
-show (EqualTo x) l = ["(EqualTo ", toString x,")":l]\r
-show (LessThen x) l = ["LessThen ", toString x,")":l]\r
-show (Not x) l = ["Not ":show x [")":l]]\r
-show (Either x1 x2) l = ["Either (":show x1 [")(":show x2 [")":l]]]\r
-\r
-assertThat :: String a (Match a) -> Test | ==, <, toString a\r
-assertThat str x y = \st=:{f,s,p}.if (eval x y)\r
- {st & s=s+1}\r
- {st & f=f+1, p=p++[toString (f+1),": AssertThat ",str," ":show y [")\n"]]}\r
+:: TestResult :== (Bool, [String])\r
+:: Test :== TestState -> TestState\r
+\r
+class Testable a | Eq, Ord, toString a\r
+\r
+instance * Test where\r
+ (*) t1 t2 = \st.let st`=t1 st in t2 st`\r
+\r
+EqualTo :: a -> (a -> TestResult) | Testable a\r
+EqualTo q = \a.(q == a, ["(EqualTo ",toString q,")"])\r
+\r
+LessThen :: a -> (a -> TestResult) | Testable a\r
+LessThen q = \a.(q < a, ["(LessThen ",toString q,")"])\r
+\r
+Not :: (a -> TestResult) -> (a -> TestResult) | Testable a\r
+Not x = \r.let (v,p)=x r in (not v, ["(Not ":p++[")"]])\r
+\r
+Is :: (a -> TestResult) -> (a -> TestResult)\r
+Is x = \r.let (v,p)=x r in (v, ["(Is ":p++[")"]])\r
+\r
+Either :: (a -> TestResult) (a -> TestResult) -> (a -> TestResult)\r
+Either x1 x2 = \r.let (v1,p1)=x1 r in let(v2,p2)=x2 r in\r
+ (v1 || v2, ["(Either ":p1++[" ":p2++[")"]]])\r
+\r
+Contains :: a -> ([a] -> TestResult) | Testable a\r
+Contains x = \r.(isMember x r, ["(Contains ",toString x,")"])\r
+\r
+ContainsString :: String -> (String -> TestResult)\r
+ContainsString s = \r.('Text'.indexOf s r <> -1,\r
+ ["(ContainsString ",toString s,")"])\r
+\r
+AssertThat :: String a (a -> TestResult) -> Test\r
+AssertThat msg q t = \st=:{s,f,p}.case t q of\r
+ (True, _) = {st & s=s+1}\r
+ (_, p`) = {st & f=f+1, \r
+ p=p++[toString (f+1),". AssertThat ",msg," ":p`++["\n"]]}\r
\r
test :: Test -> String\r
test t = 'Text'.concat ["passes=", toString s, ", fails=", toString f, "\n":p]\r
where {f,s,p}=t {s=0, f=0, p=[]}\r
\r
-instance * Test where\r
- (*) s1 s2 = \st.let st`=s1 st in s2 st`\r
-\r
-Start = test (t1 * t2 * t3)\r
+Start = test (a1 * a2 * a3 * a4 * a5 * a6)\r
where\r
- t1 = assertThat "(2*2)" (2*2) (Is (EqualTo (2+2)))\r
- t2 = assertThat "(3*3)" (3*3) (Is (EqualTo (3+3)))\r
- t3 = assertThat "(length [0..3])" (length [0..3]) (Not (EqualTo 4))\r
+ a1 = AssertThat "(2*2)" (2*2) (Is (EqualTo (2+2)))\r
+ a2 = AssertThat "(3*3)" (3*3) (Is (EqualTo (3+3)))\r
+ a3 = AssertThat "(length [0..3])" (length [0..3]) (Not (EqualTo 4))\r
+ a4 = AssertThat "[0..3]" [0..3] (Contains 2)\r
+ a5 = AssertThat "[0..3]" [0..3] (Contains 7)\r
+ a6 = AssertThat "[0..3]" [0..3] (Either (EqualTo [1]) (Contains 7))\r