Carp/core/Test.carp

136 lines
4.0 KiB
Plaintext
Raw Normal View History

2017-10-20 18:00:47 +03:00
(defmodule IO
2018-02-23 19:25:15 +03:00
(def color-table
2017-10-20 18:00:47 +03:00
[[@"black" @"30"]
[@"red" @"31"]
[@"green" @"32"]
[@"yellow" @"33"]
[@"blue" @"34"]
[@"magenta" @"35"]
[@"cyan" @"36"]
[@"white" @"37"]
[@"reset" @"0"]
[@"none" @"0"]
[@"bold" @"1"]
[@"italic" @"3"]
[@"underline" @"4"]
[@"blink-slow" @"5"]
[@"blink-rapid" @"6"]
[@"bg-black" @"40"]
[@"bg-red" @"41"]
[@"bg-green" @"42"]
[@"bg-yellow" @"43"]
[@"bg-blue" @"44"]
[@"bg-magenta" @"45"]
[@"bg-cyan" @"46"]
[@"bg-white" @"47"]])
(def len-color-table (Array.length &color-table))
2017-10-20 18:00:47 +03:00
(defn color-name-to-ansi [cname]
(let [res @""]
(do
(for [i 0 len-color-table]
2018-02-23 19:25:15 +03:00
(if (String.= cname (Array.nth (Array.nth &color-table i) 0))
(set! res @(Array.nth (Array.nth &color-table i) 1))
2017-10-20 18:00:47 +03:00
()))
(StringCopy.append @"\x1b[" (StringCopy.append res @"m")))))
2017-10-20 18:00:47 +03:00
(defn color [cname]
(print &(color-name-to-ansi cname)))
)
(defmodule Test
(deftype State [passed Int, failed Int])
2017-11-25 21:19:15 +03:00
(defn handler [state expected actual descr what op]
2017-10-20 18:00:47 +03:00
(if (op expected actual)
(do
(IO.color "green")
(IO.println &(string-join @"Test '" @descr @"' passed"))
(IO.color "reset")
(State.update-passed (State.copy state) Int.inc))
(do
(IO.color "red")
(IO.println &(string-join @"Test '" @descr @"' failed:"))
(IO.print &(string-join @"\tExpected " @what @": '"))
2017-10-20 18:00:47 +03:00
(IO.print &(str expected))
(IO.println &(string-join @"', actual value: '" (str actual) @"'"))
(IO.color "reset")
(State.update-failed (State.copy state) Int.inc))))
2017-11-25 21:19:15 +03:00
(defn assert-op [state x y descr op]
(handler state x y descr "value" op))
2017-10-20 18:00:47 +03:00
2017-11-25 21:19:15 +03:00
(defn assert-equal [state x y descr]
(handler state x y descr "value" =))
2017-10-20 18:00:47 +03:00
2017-11-25 21:19:15 +03:00
(defn assert-not-equal [state x y descr]
(handler state x y descr "not value" /=))
2017-10-20 18:00:47 +03:00
(defn assert-true [state x descr]
2017-11-25 21:19:15 +03:00
(assert-equal state true x descr))
2017-10-20 18:00:47 +03:00
(defn assert-false [state x descr]
2017-11-25 21:19:15 +03:00
(assert-equal state false x descr))
2017-10-20 18:00:47 +03:00
(defn reset [state]
(State.set-failed (State.set-passed state 0) 0))
(defn run-child [x]
(let [pid (System.fork)
status 0]
(if (= pid 0)
(x)
(do
(ignore (System.wait (address status)))
(System.get-exit-status status)))))
(defn assert-fails [state exit-code x descr]
(assert-equal state exit-code (run-child x) descr))
2017-10-20 18:00:47 +03:00
(defn print-test-results [state]
(let [passed @(State.passed state)
failed @(State.failed state)]
2017-10-20 18:00:47 +03:00
(do
(IO.println "Results:")
(if (Int.> (Int.+ passed failed) 0)
(do
(IO.color "green")
(if (Int.> passed 0) (IO.print &(StringCopy.append @"\t|" (String.repeat passed "="))) ())
2017-10-20 18:00:47 +03:00
(if (Int.= failed 0) (IO.print "|") ())
(IO.color "red")
(if (Int.= passed 0) (IO.print "\t|") ())
(if (Int.> failed 0) (IO.print &(StringCopy.append (String.repeat failed "=") @"|")) ())
2017-10-20 18:00:47 +03:00
(IO.println ""))
())
(IO.color "green")
(IO.print "\tPassed: ")
(IO.print &(Int.str passed))
(IO.color "red")
(IO.print "\tFailed: ")
(IO.println &(Int.str failed))
(IO.color "reset")
(State.copy state))))
)
(defdynamic with-test-internal [name forms]
(if (= (length forms) 1)
(list (list 'set! name (list 'ref (car forms))))
(cons (list 'set! name (list 'ref (car forms)))
2017-10-20 18:00:47 +03:00
(with-test-internal name (cdr forms)))))
(defmacro with-test [name :rest forms]
(list 'let [name '&(Test.State.init 0 0)]
(cons-last
(list 'Int.copy (list 'Test.State.failed name))
(cons 'do (with-test-internal name forms)))))
2017-10-20 18:00:47 +03:00
(defmacro deftest [name state-name :rest forms]
(list 'defn name []
(list 'let [state-name '&(Test.State.init 0 0)]
2017-10-20 18:00:47 +03:00
(cons-last
(list Test.print-test-results state-name)
(cons 'do (with-test-internal state-name forms))))))