@@ -231,7 +231,7 @@ class RunnerPanel implements ActionListener, MouseListener, HyperlinkListener {
231231 </style>
232232 </head>
233233 <body>
234- «getLinkedText (text)»
234+ «getLinkedAndFormattedText (text)»
235235 </body>
236236 </html>
237237 ' ' '
@@ -245,14 +245,16 @@ class RunnerPanel implements ActionListener, MouseListener, HyperlinkListener {
245245 var line = Integer . parseInt(parts. get(2 ))
246246 val dao = new UtplsqlDao (Connections . instance. getConnection(currentRun. connectionName))
247247 val objectType = dao. getObjectType(ownerName, objectName)
248+ // links to package specification will open the body, there is no way to identify the type without context knowledge
249+ // but the jump to the specification from the body is simple from SQL Developer, so it is a minor issue
248250 val fixedObjectType = ' ' ' «objectType»«IF objectType == "PACKAGE" || objectType == "TYPE"» BODY«ENDIF»' ' '
249251 if (parts. size == 4 ) {
250252 val procedureName = parts. get(3 )
251253 val source = dao. getSource(ownerName, fixedObjectType, objectName). trim
252254 val parser = new UtplsqlParser (source)
253255 line = parser. getLineOf(procedureName)
254256 }
255- openEditor(ownerName, ' ' ' «objectType»«IF objectType == "PACKAGE" || objectType == "TYPE"» BODY«ENDIF» ' ' ' , objectName. toUpperCase, line, 1 )
257+ openEditor(ownerName, fixedObjectType , objectName. toUpperCase, line, 1 )
256258 }
257259
258260 private def openEditor (String owner , String type , String name , int line , int col ) {
@@ -543,13 +545,14 @@ class RunnerPanel implements ActionListener, MouseListener, HyperlinkListener {
543545 }
544546 }
545547
546- private def getLinkedText (String text ) {
548+ private def getLinkedAndFormattedText (String text ) {
547549 if (text == = null ) {
548550 return " "
549551 }
550552 // Patterns (primarily Asserts, Errors, ServerOutput):
551553 // at "OWNER.PACKAGE.PROCEDURE", line 42
552554 // at "OWNER.PROCEDURE", line 42
555+ // at "OWNER.PACKAGE", line 42
553556 val p1 = Pattern . compile(' ' ' \s +("(\S +?)\. (\S +?)(?:\. (\S +?))?",\s +line\s +([0-9]+))' ' ' )
554557 var localText = HtmlUtils . htmlEscape(text)
555558 var m = p1. matcher(localText)
@@ -569,6 +572,17 @@ class RunnerPanel implements ActionListener, MouseListener, HyperlinkListener {
569572 localText = ' ' ' «localText.substring(0, start)»«link»«localText.substring(end)»' ' '
570573 m = p2. matcher(localText)
571574 }
575+ // Patterns (Title for warning/info on suite level)
576+ // from suite a.junit_utplsql_test1_pkg:
577+ val p3 = Pattern . compile(' ' ' ^For suite ([^:]+):$' ' ' , Pattern . MULTILINE )
578+ m = p3. matcher(localText)
579+ while (m. find) {
580+ val title = ' ' ' <font size="4"><b>For suite "«m.group(1)»"</b></font>' ' '
581+ val start = m. start(0 )
582+ val end = m. end(0 )
583+ localText = ' ' ' «localText.substring(0, start)»«title»«localText.substring(end)»' ' '
584+ m = p3. matcher(localText)
585+ }
572586 val result = ' ' '
573587 «FOR p : localText.split("\n ")»
574588 <p>«p»</p>
0 commit comments