marklogic-community / marklogic-unit-test

Automated testing for MarkLogic
https://marklogic-community.github.io/marklogic-unit-test/
Other
13 stars 25 forks source link

Support passing JavaScript functions to assert-throws-error #123

Open dmcassel opened 4 years ago

dmcassel commented 4 years ago

See Stack Overflow question.

test:assert-throws-error requires an xdmp:function, which isn't what you get from JavaScript.

dmcassel commented 4 years ago

Implementation notes: if we got rid of the typed parameter for test:assert-throws-error, we could check for XQuery functions like this:

$function instance of xdmp:function

Not sure how to check whether the parameter is a JS function. I think the most straightforward solution, in combination with #111, is to just do something like:

declare function test:assert-throws-error($function, $error-code as xs:string?)
{
  try {
    $function(),
    fn:error(xs:QName("ASSERT-THROWS-ERROR-FAILED"), $message-prefix || "Did not throw an error")
  } catch ($ex) {
      if ($ex/error:name eq "ASSERT-THROWS-ERROR-FAILED") then
        xdmp:rethrow()
      else if ($error-code) then
        if ($ex/error:code eq $error-code or $ex/error:name eq $error-code) then
          if ($expected-error-message and fn:not($ex/error:message/text() eq $expected-error-message)) then (
            xdmp:log($ex, "info"),
            fn:error(xs:QName("ASSERT-THROWS-ERROR-FAILED"), $message-prefix
              || "Found expected error code, but not expected message:" || " expected: [" || $expected-error-message
              || "] actual: [" || $ex/error:message/fn:string() || "]")
          )
          else
            test:success()
        else (
          xdmp:log($ex, "info"),
          fn:error(xs:QName("ASSERT-THROWS-ERROR-FAILED"), $message-prefix
              || "Did not find expected error code: expected: [" || $error-code || "] actual: ["
              || $ex/error:name/fn:string() || "]")
        )
      else
        test:success()
  }
};

Any function passed in that has multiple parameters will go to the old functions. Any function that has no parameters should just work. If someone passes in a non-function as $function, they will get an XDMP-NOTFUNC exception.

If this approach looks good to others, I'll put together a PR.