Adam Cameron
notToThrow
matcher. Here are some tests:
https://gist.github.com/adamcameron/e1674e216bd8b759fb34e663fc8a6603Adam Cameron
import test.BaseSpec
component extends=BaseSpec {
function run() {
describe("Tests TestBox assertions", () => {
describe("Tests toThrow", () => {
it("should pass because it DOES throw an exception with the matching message", () => {
expect(() => throwExceptionWithMatchingMessage()).toThrow(regex="^.*MATCH_THIS.*$")
})
})
describe("Tests notToThrow", () => {
it("should pass because it is throwing a different exception", () => {
expect(() => throwDifferentException()).notToThrow(regex="^.*MATCH_THIS.*$")
})
it("should fail because it DOES throw an exception with the matching message", () => {
expect(() => throwExceptionWithMatchingMessage()).notToThrow(regex="^.*MATCH_THIS.*$")
})
it("should fail because it DOES throw an exception with the matching detail", () => {
expect(() => throwExceptionWithMatchingDetail()).notToThrow(regex="^.*MATCH_THIS.*$")
})
it("should fail because it DOES throw an exception that matches on both message and detail", () => {
expect(() => throwExceptionWithMatchingMessageAndDetail()).notToThrow(regex="^.*MATCH_THIS.*$")
})
})
})
}
function throwExceptionWithMatchingMessage() {
throw(message="MESSAGE_MATCH_THIS")
}
function throwExceptionWithMatchingDetail() {
throw(detail="DETAIL_MATCH_THIS")
}
function throwExceptionWithMatchingMessageAndDetail() {
throw(message="BOTH_MATCH_THIS", detail="BOTH_MATCH_THIS")
}
function throwDifferentException() {
throw(message="DIFFERENT_MESSAGE", detail="DETAIL_MATCH_THIS")
}
}
The results are:
https://i2.paste.pics/36545bd5ab233a462046e1bd02431eef.png▾
Adam Cameron
Adam Cameron
if (
len( arguments.regex ) AND
(
!arrayLen( reMatchNoCase( arguments.regex, e.message ) )
OR
!arrayLen( reMatchNoCase( arguments.regex, e.detail ) )
)
) {
return this;
}
The problem here seems to stem from the assertion using the same regex for both message and detail which isn't that sensible for real world situations, as they're unlikely to be the same. So for this logic to actually work, the regex provided needs to cover BOTH message and detail simultaneously.
For example: if I only want to match the message... then the detail match will fail. So: the assertion will determine that it's a different exception, so the assertion passes. Even though my regex is only supposed to be targeting the message. This is especially clear in situations where there isn't any detail... the logic still checks it, it doesn't match, so the condition passes and the exception is deemed to be different.
On the other hand if I only want to match the detail with my regex... this logic fails for the same reason: the message won't match, so the exception is deemed to be different. Even though my desire was to only match the detail.
I get that the assertion has no way of knowing which of message or detail I am actually wanting to match... this is the whole problem. It needs to know.Adam Cameron
// if the type is different, the exception is different: pass
if ( len( arguments.type ) AND e.type neq arguments.type ) {
return this;
}
if (! len( arguments.regex )) {
// we have to infer it's the same exception as there's nothing else to go on
fail( arguments.message );
}
if (arrayLen( reMatchNoCase( arguments.regex, e.message ) )) {
// we found the regex in the message so we have to infer that's what they were checking. So it's the same exception
fail( arguments.message );
}
if (arrayLen( reMatchNoCase( arguments.regex, e.detail ) )) {
// we found the regex in the detail so we have to infer that's what they were checking. So it's the same exception
fail( arguments.message );
}
// if we get to here there was no match on either message or detail, soit was a different exception: all good
return this;
(note: PLEASE don't put compound negative conditions in the same if statement. It makes the logic much harder to follow. Just check one thing at a time, and early exit)
This approach won't work in the one situation where the regex was intended to match the details
and it wouldn't have, but it does coincidentally match the message, so details
are never checked. I think this is the minimum cost of using one regex for both. And it's very unlikely to be true.
I think you might also want to add an extra optional param that is detailsRegex
, and the behaviour of checking regex
is still applied to message
and detail
, but detailsRegex
can be used to only check the details
. This works-around the shortfall in my logic above.Adam Cameron
Adam Cameron
bdw429s
04/18/2022, 6:48 PMAdam Cameron
bdw429s
04/18/2022, 6:59 PMAdam Cameron
Adam Cameron