Created
October 29, 2013 03:47
-
-
Save rabuf/7208921 to your computer and use it in GitHub Desktop.
This is the test framework I put together for the SML portion of the Coursera class "Programming Languages", taught by Dan Grossman. I preferred this format to a series of dozens of assignments like `val test<n> = <some function call> = <some result>`
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(* Test framework, since we only submit 2 files I'm copy/pasting this here *) | |
datatype (''a,''b) testcase = | |
TestCase of ''a * ''b * string | |
| TestCaseException of ''a * exn * string | |
datatype 'a testresult = Pass | Fail of 'a | |
datatype ('a,'b,'c) test = Test of 'c * ('a,'b) testcase list | |
fun test (Test (f,cases)) = | |
let fun aux cases acc = | |
case cases of | |
[] => acc | |
| (t as TestCase (p,r,s))::cs => (if f p = r | |
then aux cs (Pass::acc) | |
else aux cs (Fail t::acc)) | |
| (t as TestCaseException (p,e,s))::cs => (((f p); aux cs (Fail t::acc)) | |
handle | |
e' => if exnName e' = exnName e | |
then aux cs (Pass::acc) | |
else aux cs (Fail t::acc)) | |
in | |
aux cases [] | |
end | |
fun make_test f cases = Test (f,cases) | |
fun make_case params result description = TestCase (params, result, description) | |
fun make_case_exception params ex description = TestCaseException (params, ex, description) | |
val test_only_capitals = | |
make_test only_capitals | |
[make_case [] [] "empty list", | |
make_case ["A"] ["A"] "list of one element, capitalized", | |
make_case ["a"] [] "list of one element, lowercase", | |
make_case ["A","b"] ["A"] "list of 2 elements, one capitalized"] | |
(* The local value longest_string_helper lets me uncurry the function call, my test framework | |
can't handle curried functions. If I had more time and motivation (I think we're done with SML) | |
I'd make the parameter part a list, then call the function f with the first value in the list, | |
call the result with the second value, repeating until the parameter list were exhausted. | |
Conveniently this would work for curried and uncurried functions. I just haven't done it. *) | |
val test_longest_string_helper = | |
let val longest_string_helper = fn (f,s) => longest_string_helper f s | |
in | |
make_test longest_string_helper | |
[make_case ((op >),[] : string list) "" "Empty string for an emtpy list", | |
make_case ((op >),["AA","BB"]) "AA" "Should get earliest longest entry", | |
make_case ((op >=),["AA","BB"]) "BB" "Should get latest longest entry"] | |
val test1 = test test_only_capitals | |
val test4a = test test_longest_string_helper | |
(* `test_only_capitals` contains the test details, `test` has to be called on it to evaluate them. | |
I numbered the test result based on the problem number, so test1 is problem 1, test 4a would be | |
problem 4a. *) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment