11/*
2+ * Elemental
3+ * Copyright (C) 2024, Evolved Binary Ltd
4+ *
5+ 6+ * https://www.evolvedbinary.com | https://www.elemental.xyz
7+ *
8+ * This library is free software; you can redistribute it and/or
9+ * modify it under the terms of the GNU Lesser General Public
10+ * License as published by the Free Software Foundation; version 2.1.
11+ *
12+ * This library is distributed in the hope that it will be useful,
13+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15+ * Lesser General Public License for more details.
16+ *
17+ * You should have received a copy of the GNU Lesser General Public
18+ * License along with this library; if not, write to the Free Software
19+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20+ *
21+ * NOTE: Parts of this file contain code from 'The eXist-db Authors'.
22+ * The original license header is included below.
23+ *
24+ * =====================================================================
25+ *
226 * eXist-db Open Source Native XML Database
327 * Copyright (C) 2001 The eXist-db Authors
428 *
1943 * License along with this library; if not, write to the Free Software
2044 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
2145 */
22-
2346package org .exist .test .runner ;
2447
2548import org .exist .xquery .ErrorCodes ;
4063
4164public class ExtTestErrorFunction extends JUnitIntegrationFunction {
4265
66+ private static final StringValue DESCRIPTION_MAP_KEY = new StringValue ("description" );
67+ private static final StringValue CODE_MAP_KEY = new StringValue ("code" );
68+ private static final StringValue LINE_NUMBER_MAP_KEY = new StringValue ("line-number" );
69+ private static final StringValue COLUMN_NUMBER_MAP_KEY = new StringValue ("column-number" );
70+ private static final StringValue JAVA_STACK_TRACE_MAP_KEY = new StringValue ("java-stack-trace" );
71+
4372 public ExtTestErrorFunction (final XQueryContext context , final String parentName , final RunNotifier notifier ) {
4473 super ("ext-test-error-function" ,
4574 params (
@@ -50,67 +79,67 @@ public ExtTestErrorFunction(final XQueryContext context, final String parentName
5079
5180 @ Override
5281 public Sequence eval (final Sequence contextSequence , final Item contextItem ) throws XPathException {
53- final Sequence arg1 = getCurrentArguments ()[0 ];
54- final String name = arg1 .itemAt (0 ).getStringValue ();
82+ final Sequence [] args = getCurrentArguments ();
83+ if (args .length != 2 ) {
84+ throw new XPathException (this , "ext-test-error-function requires 2 parameters" );
85+ }
86+
87+ final Sequence argName = args [0 ];
88+ if (argName .isEmpty ()) {
89+ throw new XPathException (this , "ext-test-error-function requires a 'name' parameter" );
90+ }
91+ final String name = safeGetStringValue (argName .itemAt (0 ));
5592
56- final Sequence arg2 = getCurrentArguments (). length == 2 ? getCurrentArguments () [1 ] : null ;
57- final MapType error = arg2 != null ? (MapType )arg2 .itemAt (0 ) : null ;
93+ final Sequence argError = args [1 ];
94+ @ Nullable final MapType error = argError . isEmpty () ? null : (MapType ) argError .itemAt (0 );
5895
5996 final Description description = createTestDescription (name );
6097
6198 // notify JUnit
6299 try {
63- final XPathException errorReason = errorMapAsXPathException (error );
64- notifier .fireTestFailure (new Failure (description , errorReason ));
65- } catch (final XPathException e ) {
100+ final Failure failure ;
101+ if (error != null ) {
102+ final XPathException errorReason = errorMapAsXPathException (error );
103+ failure = new Failure (description , errorReason );
104+ } else {
105+ failure = new Failure (description , new XPathException (this , "No error map provided to ext-test-error-function" ));
106+ }
107+ notifier .fireTestFailure (failure );
108+ } catch (final Throwable t ) {
66109 //signal internal failure
67- notifier .fireTestFailure (new Failure (description , e ));
110+ notifier .fireTestFailure (new Failure (description , t ));
68111 }
69112
70113 return Sequence .EMPTY_SEQUENCE ;
71114 }
72115
73- private XPathException errorMapAsXPathException (final MapType errorMap ) throws XPathException {
74- final Sequence seqDescription = errorMap .get (new StringValue (this , "description" ));
75- final String description ;
76- if (seqDescription != null && !seqDescription .isEmpty ()) {
77- description = seqDescription .itemAt (0 ).getStringValue ();
78- } else {
79- description = "" ;
80- }
116+ private XPathException errorMapAsXPathException (final MapType errorMap ) {
117+ final Sequence seqDescription = errorMap .get (DESCRIPTION_MAP_KEY );
118+ final String description = safeGetMapStringValue (DESCRIPTION_MAP_KEY , errorMap , "" );
81119
82- final Sequence seqErrorCode = errorMap .get (new StringValue ( this , "code" ) );
120+ final Sequence seqErrorCode = errorMap .get (CODE_MAP_KEY );
83121 final ErrorCodes .ErrorCode errorCode ;
84122 if (seqErrorCode != null && !seqErrorCode .isEmpty ()) {
85123 errorCode = new ErrorCodes .ErrorCode (((QNameValue )seqErrorCode .itemAt (0 )).getQName (), description );
86124 } else {
87125 errorCode = ErrorCodes .ERROR ;
88126 }
89127
90- final Sequence seqLineNumber = errorMap .get (new StringValue (this , "line-number" ));
91- final int lineNumber ;
92- if (seqLineNumber != null && !seqLineNumber .isEmpty ()) {
93- lineNumber = seqLineNumber .itemAt (0 ).toJavaObject (int .class );
94- } else {
95- lineNumber = -1 ;
96- }
128+ final Sequence seqLineNumber = errorMap .get (LINE_NUMBER_MAP_KEY );
129+ final int lineNumber = safeGetIntValue (seqLineNumber , 0 );
97130
98- final Sequence seqColumnNumber = errorMap .get (new StringValue (this , "column-number" ));
99- final int columnNumber ;
100- if (seqColumnNumber != null && !seqColumnNumber .isEmpty ()) {
101- columnNumber = seqColumnNumber .itemAt (0 ).toJavaObject (int .class );
102- } else {
103- columnNumber = -1 ;
131+ final Sequence seqColumnNumber = errorMap .get (COLUMN_NUMBER_MAP_KEY );
132+ final int columnNumber = safeGetIntValue (seqColumnNumber , 0 );
133+
134+ @ Nullable StackTraceElement [] stackTraceElements = null ;
135+ @ Nullable final Sequence seqJavaStackTrace = errorMap .get (JAVA_STACK_TRACE_MAP_KEY );
136+ if (seqJavaStackTrace != null && !seqJavaStackTrace .isEmpty ()) {
137+ stackTraceElements = convertStackTraceElements (seqJavaStackTrace );
104138 }
105139
106140 final XPathException xpe = new XPathException (lineNumber , columnNumber , errorCode , description );
107-
108- @ Nullable final Sequence seqJavaStackTrace = errorMap .get (new StringValue (this , "java-stack-trace" ));
109- if (seqJavaStackTrace != null && !seqJavaStackTrace .isEmpty ()) {
110- @ Nullable final StackTraceElement [] stackTraceElements = convertStackTraceElements (seqJavaStackTrace );
111- if (stackTraceElements != null ) {
112- xpe .setStackTrace (stackTraceElements );
113- }
141+ if (stackTraceElements != null ) {
142+ xpe .setStackTrace (stackTraceElements );
114143 }
115144
116145 return xpe ;
@@ -119,16 +148,16 @@ private XPathException errorMapAsXPathException(final MapType errorMap) throws X
119148 private static final Pattern PTN_CAUSED_BY = Pattern .compile ("Caused by:\\ s([a-zA-Z0-9_$\\ .]+)(?::\\ s(.+))?" );
120149 private static final Pattern PTN_AT = Pattern .compile ("at\\ s((?:[a-zA-Z0-9_$]+)(?:\\ .[a-zA-Z0-9_$]+)*)\\ .((?:[a-zA-Z0-9_$-]+)|(?:<init>))\\ (([a-zA-Z0-9_]+\\ .java):([0-9]+)\\ )" );
121150
122- protected @ Nullable StackTraceElement [] convertStackTraceElements (final Sequence seqJavaStackTrace ) throws XPathException {
151+ protected @ Nullable StackTraceElement [] convertStackTraceElements (final Sequence seqJavaStackTrace ) {
123152 StackTraceElement [] traceElements = null ;
124153
125154 final Matcher matcherAt = PTN_AT .matcher ("" );
126155
127156 // index 0 is the first `Caused by: ...`
128157 int i = 1 ;
129158 for ( ; i < seqJavaStackTrace .getItemCount (); i ++) {
130- final String item = seqJavaStackTrace .itemAt (i ). getStringValue ( );
131- final StackTraceElement stackTraceElement = convertStackTraceElement (matcherAt , item );
159+ final String item = safeGetStringValue ( seqJavaStackTrace .itemAt (i ));
160+ @ Nullable final StackTraceElement stackTraceElement = convertStackTraceElement (matcherAt , item );
132161 if (stackTraceElement == null ) {
133162 break ;
134163 }
@@ -153,7 +182,7 @@ private XPathException errorMapAsXPathException(final MapType errorMap) throws X
153182 final String methodName = matcherAt .group (2 );
154183 final String fileName = matcherAt .group (3 );
155184 final String lineNumber = matcherAt .group (4 );
156- return new StackTraceElement (declaringClass , methodName , fileName , Integer .valueOf (lineNumber ));
185+ return new StackTraceElement (declaringClass , methodName , fileName , Integer .parseInt (lineNumber ));
157186 } else {
158187 return null ;
159188 }
0 commit comments