Tim
12/18/2023, 4:33 PMgetThreatLevelName(-1) is throwing The THREATLEVEL argument passed to the getThreatLevelName function is not of type numeric.
So I'm trying to figure out what it's really getting passed, because it is obviously not -1, which absolutely is numeric.
I've tried changing the function arg to any and then dumping it. But it gives me a stack overflow, like it's some sort of recursive object. So I'm wondering if there's a better way to find out what type this mystery value is.Patrick
12/18/2023, 4:56 PMPatrick
12/18/2023, 4:56 PMMyka Forrest
12/18/2023, 4:56 PMTim
12/18/2023, 4:57 PMPatrick
12/18/2023, 4:59 PMPatrick
12/18/2023, 5:01 PMany and it is still failing, sounds like there is a bigger issue going onTim
12/18/2023, 5:09 PMcomponent {
boolean function toHaveRecords(required expectation, args={}) {
try {
var records = new Parser().parseDataLayer(expectation.actual);
var level = args.keyExists("1") && IsNumeric(args[1]) ? args[1] : 0;
expectation.message = args.keyExists("message") ? args.message : "The alert has [#records.len()#] record(s) at [#getThreatLevelName(level)#].";
if( expectation.isNot ) {
return records.len() == 0;
}
return records.len() > 0;
}
catch( any exception ) {
fail(exception.message);
}
}
private string function getThreatLevelName(required numeric threatLevel) {
switch( threatLevel ) {
case 1:
return "Severe (red)";
case 2:
return "High (orange)";
case 3:
return "Elevated (yellow)";
case 4:
return "Guarded (blue)";
case 5:
return "Low (green)";
default:
return "Unknown";
}
}
...
}Tim
12/18/2023, 5:10 PMtoHaveRecords is defined. And it calls getThreatLevelName to get a human -readable failure message.Tim
12/18/2023, 5:11 PMTim
12/18/2023, 5:12 PMlevel wasn't numeric. So I dumped it, and found it to be -1.
So then I hardcoded -1 into that line. And still get the same error. That's the point at which I posted here.Paul Gallo
12/18/2023, 5:13 PMTim
12/18/2023, 5:14 PM(expectation, args), so that my "threatlevel" argument is treated as an expectation, and the -1 isn't getting used.websolete
12/18/2023, 5:35 PMTim
12/18/2023, 6:13 PMPatrick
12/18/2023, 6:19 PMPatrick
12/18/2023, 6:19 PMTim
12/18/2023, 6:21 PMswitch is complaining that threatLevel is not a simple value. Because it is, in fact, an expectation object. TestBox is doing something funky, which is not obvious from within my code.Patrick
12/18/2023, 6:21 PMcase 1 etc needs to be case "1"Patrick
12/18/2023, 6:23 PMgetThreatLevelName() function needs to just receive a simple number...websolete
12/18/2023, 6:23 PM[#getThreatLevelName(threatLevel=level)#Patrick
12/18/2023, 6:24 PMvar level abort and see what it is returning (aka a number or not).Tim
12/18/2023, 6:26 PMwebsolete
12/18/2023, 6:26 PMTim
12/18/2023, 6:27 PMgetThreatLevelName(expectation, {1: -1}websolete
12/18/2023, 6:27 PMTim
12/18/2023, 6:28 PMwebsolete
12/18/2023, 6:28 PMTim
12/18/2023, 6:30 PMboolean function(expectation, args={}) So I think it's assuming that all public functions are custom expectations, and calling them as such.Tim
12/18/2023, 6:30 PMPatrick
12/18/2023, 6:40 PMTim
12/18/2023, 6:41 PMPatrick
12/18/2023, 6:42 PMswitch( arguments.threatlevel ) have any affect?Tim
12/18/2023, 6:43 PMpublic string function getThreatLevelName(required any expectation, args={}) {
var threatLevel = args.keyExists("threatLevel") && IsNumeric(args.threatLevel) ? args.threatLevel : 0;
switch( threatLevel ) {
case 1:
return "Severe (red)";
case 2:
return "High (orange)";
case 3:
return "Elevated (yellow)";
case 4:
return "Guarded (blue)";
case 5:
return "Low (green)";
default:
return "Unknown";
}
}Tim
12/18/2023, 6:43 PM"Unknown" is not a boolean.Tim
12/18/2023, 6:43 PMPatrick
12/18/2023, 6:43 PMPatrick
12/18/2023, 6:45 PMtoHaveRecords() returns anything other than a number...Patrick
12/18/2023, 6:45 PMTim
12/18/2023, 6:45 PMboolean function myCustomMatcher(required any expectation, struct args={}).
and then calling the function as if it matches the prototype, which is does not.Tim
12/18/2023, 6:45 PMPatrick
12/18/2023, 6:47 PMany on the function?Tim
12/18/2023, 6:47 PMTim
12/18/2023, 6:48 PMPatrick
12/18/2023, 6:50 PMwebsolete
12/18/2023, 7:05 PMcomponent {
public boolean function toHaveRecords(required expectation, args={}) {
try {
var records = new Parser().parseDataLayer(expectation.actual);
var level = args.keyExists("1") && IsNumeric(args[1]) ? args[1] : 0;
expectation.message = args.keyExists("message") ? args.message : "The alert has [#records.len()#] record(s) at [#$_getThreatLevelName(level)#].";
if( expectation.isNot ) {
return records.len() == 0;
}
return records.len() > 0;
}
catch( any exception ) {
fail(exception.message);
}
}
private string function getThreatLevelName(required numeric threatLevel) {
switch( threatLevel ) {
case 1:
return "Severe (red)";
case 2:
return "High (orange)";
case 3:
return "Elevated (yellow)";
case 4:
return "Guarded (blue)";
case 5:
return "Low (green)";
default:
return "Unknown";
}
}
public any function onMissingMethod(
required string missingMethodName,
required struct missingMethodArguments
) {
try {
// see if we're proxying a method call we want to ensure is called as expected
var targetMethodName = rereplace( arguments.missingMethodName, "^\$_", "" );
var targetMethodArguments = arguments.missingMethodArguments.keyExists("args") ? arguments.missingMethodArguments.args : {};
if( structkeyexists( this, targetMethodName ) ) {
return invoke( this, targetMethodName, targetMethodArguments );
}
else {
throw( type="InvalidMethod", message="The " & arguments.targetMethodName & " method does not exist" );
}
}
catch( any e ) {
rethrow;
}
}
}
where you prefix your private methods with $_ within your tests, but the method signatures are unmodifiedwebsolete
12/18/2023, 7:06 PMgetThreatLevelName( becomes $_getThreatLevelName( when you're calling it from the testTim
12/18/2023, 8:54 PMTim
12/18/2023, 10:18 PMonMissingMethod(expectation, args) so you just get an error that missingMethodName is not a stringTim
12/18/2023, 10:19 PMbkbk
12/19/2023, 8:02 AMlevel is being passed as a string? What happens when you test the following:
var level = args.keyExists("1") && IsNumeric(args[1]) ? args[1] : 0;
level=val(level);
expectation.message = args.keyExists("message") ? args.message : "The alert has [#records.len()#] record(s) at [#getThreatLevelName(level)#].";