В SML, как утверждать, что создается конкретное исключение?

не прилагая усилий, чтобы фактически клонировать JUnit или что-то еще, я бросаю вместе несколько функций утилиты, чтобы помочь протестировать некоторый SML-код. Я знаю о QCheck, но он не может сделать эту одну вещь, и это не то, что я хочу вообще. (Но если вы знаете о другой структуре автоматического тестирования для SML, пожалуйста, говорите.)

Я хотел бы иметь возможность утверждать, что некоторая функция вызовет исключение, например, учитывая функцию

fun broken x = raise Fail

Я хотел бы иметь возможность напишите что-нибудь вроде

throws ("ERROR: function is not broken enough!", fn () => broken 1, Fail)

и пусть он выдает ошибку, если данная функция делает не поднять ожидаемое исключение.

Я пытался написать

1 ответов


эта функция должна работать:

exception ERROR of string option;

fun throwError msg = raise ERROR (SOME msg);

fun throws (msg, func, e) =
    (func (); throwError msg) handle e' =>
        if exnName e = exnName e'
        then ()
        else raise throwError msg

Это использует функцию exnName, который получает имя исключения в виде строки и использует его для сравнения.

что еще более важно, он также обрабатывает случай, когда никакое исключение не бросается вообще, и дает ошибку на этом тоже.

кроме того, если вам просто нужно логическое значение, указывающее, является ли исключение или нет, вы можете использовать:

fun bthrows (func, e) = (func (); false) handle e' => exnName e = exnName e'

обратите внимание, что в случае сбоя вам фактически придется создать экземпляр исключения Fail, например, так:

throws ("ERROR: Oh no!", fn () => test 5, Fail "")

кроме того, вы можете взять имя исключения для более чистого общего случая:

fun throws (msg, func, e) =
    (func (); throwError msg) handle e' =>
        if e = exnName e'
        then ()
        else raise throwError msg

fun bthrows (func, e) = (func (); false) handle e' => e = exnName e'

а затем используйте его так:

throws ("ERROR: Oh no!", fn () => test 5, "Fail")