Skip to content

Instantly share code, notes, and snippets.

@rabuf
Created October 29, 2013 03:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rabuf/7208921 to your computer and use it in GitHub Desktop.
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>`
(* 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