@@ -457,7 +457,7 @@ object EvaluatorTests extends TestSuite {
457457 )
458458 }
459459
460- assert(ex.getMessage.contains(" Function parameter y not bound in call" ))
460+ assert(ex.getMessage.contains(" Function newParams parameter y not bound in call" ))
461461 }
462462
463463 test(" invalidParam" ) {
@@ -475,7 +475,7 @@ object EvaluatorTests extends TestSuite {
475475 )
476476 }
477477
478- assert(ex.getMessage.contains(" Function has no parameter hello" ))
478+ assert(ex.getMessage.contains(" Function Person has no parameter hello" ))
479479 }
480480
481481 test(" unknownVariable" ) {
@@ -866,6 +866,86 @@ object EvaluatorTests extends TestSuite {
866866 }
867867 }
868868
869+ test(" builtinErrorMessageIncludesFunctionName" ) {
870+ // Issue #416: error messages for builtin functions should include the function name.
871+
872+ // Too many args
873+ test(" tooManyArgs" ) {
874+ val ex = assertThrows[Exception ] {
875+ eval(" std.length([1], [2])" , useNewEvaluator = useNewEvaluator)
876+ }
877+ assert(ex.getMessage.contains(" Too many args, function length has" ))
878+ }
879+
880+ // Parameter not bound in call (missing required arg)
881+ test(" missingRequiredArg" ) {
882+ val ex = assertThrows[Exception ] {
883+ eval(" std.substr('hello')" , useNewEvaluator = useNewEvaluator)
884+ }
885+ assert(ex.getMessage.contains(" Function substr parameter" ))
886+ assert(ex.getMessage.contains(" not bound in call" ))
887+ }
888+
889+ // Function has no parameter (invalid named arg)
890+ test(" invalidNamedArg" ) {
891+ val ex = assertThrows[Exception ] {
892+ eval(" std.length(x=[1], noSuchParam=2)" , useNewEvaluator = useNewEvaluator)
893+ }
894+ assert(ex.getMessage.contains(" Function length has no parameter noSuchParam" ))
895+ }
896+
897+ // Binding parameter a second time
898+ test(" duplicateArg" ) {
899+ val ex = assertThrows[Exception ] {
900+ eval(" std.pow(2, x=3)" , useNewEvaluator = useNewEvaluator)
901+ }
902+ assert(ex.getMessage.contains(" binding parameter a second time: x in function pow" ))
903+ }
904+
905+ // User-defined function should include function name from local binding
906+ test(" userDefinedFunctionIncludesFunctionName" ) {
907+ val ex = assertThrows[Exception ] {
908+ eval(
909+ """ local myFunc(x, y) = x + y;
910+ |myFunc("a")
911+ """ .stripMargin,
912+ useNewEvaluator = useNewEvaluator
913+ )
914+ }
915+ assert(ex.getMessage.contains(" Function myFunc parameter y not bound in call" ))
916+ }
917+
918+ // User-defined function: too many args should include function name
919+ test(" userDefinedTooManyArgs" ) {
920+ val ex = assertThrows[Exception ] {
921+ eval(
922+ """ local add(x, y) = x + y;
923+ |add(1, 2, 3)
924+ """ .stripMargin,
925+ useNewEvaluator = useNewEvaluator
926+ )
927+ }
928+ assert(ex.getMessage.contains(" Too many args, function add has 2 parameter(s)" ))
929+ }
930+
931+ // Anonymous function should NOT include function name in error message
932+ test(" anonymousFunctionNoFunctionName" ) {
933+ val ex = assertThrows[Exception ] {
934+ eval(" (function(x, y) x + y)('a')" , useNewEvaluator = useNewEvaluator)
935+ }
936+ // Should be exactly "Function parameter..." without a function name inserted
937+ assert(ex.getMessage.contains(" Function parameter y not bound in call" ))
938+ }
939+
940+ // Anonymous function: too many args should NOT include function name
941+ test(" anonymousFunctionTooManyArgs" ) {
942+ val ex = assertThrows[Exception ] {
943+ eval(" (function(x) x)(1, 2)" , useNewEvaluator = useNewEvaluator)
944+ }
945+ assert(ex.getMessage.contains(" Too many args, function has 1 parameter(s)" ))
946+ }
947+ }
948+
869949 }
870950 def tests : Tests = allTests(false ).prefix(" Evaluator" ) ++ allTests(true ).prefix(" NewEvaluator" )
871951}
0 commit comments