diff --git a/.gitignore b/.gitignore
index 410561c1..ba2ce844 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,27 +1,47 @@
+# Compiled class file
*.class
-*._trace
-*.xtendbin
-*.DS_Store
+
+# Log file
*.log
-**/target
-**/bin
-**/test-output
-**/xtend-gen
-**/.sonar
-**/.project
-**/.classpath
-**/.settings
-**/.idea
-# Mobile Tools for Java (J2ME)
-.mtj.tmp/
-# Package Files #
+
+# Package Files
*.jar
*.war
+*.nar
*.ear
+*.zip
+*.tar.gz
+*.rar
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
+# Xtend
+*._trace
+*.xtendbin
+**/xtend-gen
+
+# SonarQube
+**/.sonar
+**/.scannerwork
+
+# Eclipse / Visual Studio Code
+.project
+.classpath
+**/.settings
+
+# IntelliJ
+**/.idea
+*.iml
+
+# macOS
+*.DS_Store
+
+# Windows
Thumbs.db
+
+# Targets
+**/target
+**/bin
diff --git a/sqldev/extension.xml b/sqldev/extension.xml
index 835e262c..88d49292 100644
--- a/sqldev/extension.xml
+++ b/sqldev/extension.xml
@@ -106,6 +106,13 @@
Code-Editor
+
+
+ ${MENU_DEBUG_TEST_LABEL}
+ res:/org/utplsql/sqldev/resources/images/debug.png
+ Code-Editor
+
+
${MENU_GENERATE_TEST_LABEL}
@@ -120,6 +127,7 @@
+
@@ -132,7 +140,8 @@
id="UTPLSQL_MENU" weight="2.0">
-
+
+
@@ -142,7 +151,8 @@
diff --git a/sqldev/pom.xml b/sqldev/pom.xml
index 86c63539..7d3f85b4 100644
--- a/sqldev/pom.xml
+++ b/sqldev/pom.xml
@@ -1,3 +1,4 @@
+
4.0.0
@@ -142,6 +143,20 @@
system
${sqldev.basedir}/jdev/extensions/oracle.jdeveloper.java.core.jar
+
+ oracle
+ oracle.jdeveloper.runner.jar
+ 13.0.0
+ system
+ ${sqldev.basedir}/jdev/extensions/oracle.jdeveloper.runner.jar
+
+
+ oracle
+ oracle.ide.runner
+ 19.3.0
+ system
+ ${sqldev.basedir}/ide/extensions/oracle.ide.runner.jar
+
oracle
@@ -172,6 +187,12 @@
spring-jdbc
5.2.6.RELEASE
+
+
+ org.springframework
+ spring-core
+ 5.2.6.RELEASE
+
org.springframework
@@ -191,7 +212,13 @@
4.12
test
-
+
+ org.jetbrains
+ annotations
+ 13.0
+ compile
+
+
@@ -370,6 +397,13 @@
+
+
+
+
+
+
+
org.apache.felix
maven-bundle-plugin
4.2.1
@@ -405,9 +439,11 @@
oracle.javatools,
oracle.javatools-nodeps,
oracle.jdeveloper.db.connection,
+ oracle.jdeveloper.runner,
oracle.idert,
oracle.ide,
oracle.ide.db,
+ oracle.ide.runner,
oracle.sqldeveloper,
oracle.sqldeveloper.utils,
oracle.sqldeveloper.worksheet,
diff --git a/sqldev/src/main/java/org/utplsql/sqldev/dal/RealtimeReporterDao.java b/sqldev/src/main/java/org/utplsql/sqldev/dal/RealtimeReporterDao.java
index 042d6810..e5196306 100644
--- a/sqldev/src/main/java/org/utplsql/sqldev/dal/RealtimeReporterDao.java
+++ b/sqldev/src/main/java/org/utplsql/sqldev/dal/RealtimeReporterDao.java
@@ -17,11 +17,9 @@
import java.io.IOException;
import java.io.StringReader;
-import java.sql.CallableStatement;
import java.sql.Clob;
import java.sql.Connection;
import java.sql.ResultSet;
-import java.sql.SQLException;
import java.util.List;
import java.util.logging.Logger;
@@ -54,12 +52,13 @@
import oracle.jdbc.OracleTypes;
+@SuppressWarnings("StringBufferReplaceableByString")
public class RealtimeReporterDao {
private static final Logger logger = Logger.getLogger(RealtimeReporterDao.class.getName());
private static final int FIRST_VERSION_WITH_REALTIME_REPORTER = 3001004;
private final XMLTools xmlTools = new XMLTools();
- private Connection conn;
- private JdbcTemplate jdbcTemplate;
+ private final Connection conn;
+ private final JdbcTemplate jdbcTemplate;
public RealtimeReporterDao(final Connection conn) {
this.conn = conn;
@@ -72,12 +71,23 @@ public boolean isSupported() {
.normalizedUtPlsqlVersionNumber() >= RealtimeReporterDao.FIRST_VERSION_WITH_REALTIME_REPORTER;
}
- public void produceReport(final String reporterId, final List pathList) {
+ // used for execution via PL/SQL Debugger
+ public String getProduceReportPlsql(final String reporterId, final List pathList) {
+ return getProduceReportPlsql(reporterId, pathList, false);
+ }
+
+ private String getProduceReportPlsql(final String reporterId, final List pathList, boolean useBindVariable) {
StringBuilder sb = new StringBuilder();
sb.append("DECLARE\n");
sb.append(" l_reporter ut_realtime_reporter := ut_realtime_reporter();\n");
sb.append("BEGIN\n");
- sb.append(" l_reporter.set_reporter_id(?);\n");
+ if (useBindVariable) {
+ sb.append(" l_reporter.set_reporter_id(?);\n");
+ } else {
+ sb.append(" l_reporter.set_reporter_id('");
+ sb.append(reporterId);
+ sb.append("');\n");
+ }
sb.append(" l_reporter.output_buffer.init();\n");
sb.append(" sys.dbms_output.enable(NULL);\n");
sb.append(" ut_runner.run(\n");
@@ -88,7 +98,11 @@ public void produceReport(final String reporterId, final List pathList)
sb.append(" );\n");
sb.append(" sys.dbms_output.disable;\n");
sb.append("END;");
- final String plsql = sb.toString();
+ return sb.toString();
+ }
+
+ public void produceReport(final String reporterId, final List pathList) {
+ final String plsql = getProduceReportPlsql(reporterId, pathList, true);
final Object[] binds = { reporterId };
jdbcTemplate.update(plsql, binds);
}
@@ -135,35 +149,37 @@ public void produceReportWithCoverage(final String realtimeReporterId, final Str
}
public void consumeReport(final String reporterId, final RealtimeReporterEventConsumer consumer) {
+ consumeReport(reporterId, consumer, 60);
+ }
+
+ public void consumeReport(final String reporterId, final RealtimeReporterEventConsumer consumer, final int timeoutSeconds) {
StringBuilder sb = new StringBuilder();
sb.append("DECLARE\n");
sb.append(" l_reporter ut_realtime_reporter := ut_realtime_reporter();\n");
sb.append("BEGIN\n");
sb.append(" l_reporter.set_reporter_id(?);\n");
- sb.append(" ? := l_reporter.get_lines_cursor();\n");
+ sb.append(" ? := l_reporter.get_lines_cursor(a_initial_timeout => ?);\n");
sb.append("END;");
final String plsql = sb.toString();
jdbcTemplate.setFetchSize(1);
try {
- jdbcTemplate.execute(plsql, new CallableStatementCallback() {
- @Override
- public Void doInCallableStatement(final CallableStatement cs) throws SQLException {
- cs.setString(1, reporterId);
- cs.registerOutParameter(2, OracleTypes.CURSOR);
- cs.execute();
- final ResultSet rs = (ResultSet) cs.getObject(2);
- while (rs.next()) {
- final String itemType = rs.getString("item_type");
- final Clob textClob = rs.getClob("text");
- final String textString = textClob.getSubString(1, ((int) textClob.length()));
- final RealtimeReporterEvent event = convert(itemType, textString);
- if (event != null) {
- consumer.process(event);
- }
+ jdbcTemplate.execute(plsql, (CallableStatementCallback) cs -> {
+ cs.setString(1, reporterId);
+ cs.setInt(3, timeoutSeconds);
+ cs.registerOutParameter(2, OracleTypes.CURSOR);
+ cs.execute();
+ final ResultSet rs = (ResultSet) cs.getObject(2);
+ while (rs.next()) {
+ final String itemType = rs.getString("item_type");
+ final Clob textClob = rs.getClob("text");
+ final String textString = textClob.getSubString(1, ((int) textClob.length()));
+ final RealtimeReporterEvent event = convert(itemType, textString);
+ if (event != null) {
+ consumer.process(event);
}
- rs.close();
- return null;
}
+ rs.close();
+ return null;
});
} finally {
jdbcTemplate.setFetchSize(UtplsqlDao.FETCH_ROWS);
@@ -179,24 +195,21 @@ public String getHtmlCoverage(final String reporterId) {
sb.append(" ? := l_reporter.get_lines_cursor();\n");
sb.append("END;");
final String plsql = sb.toString();
- return jdbcTemplate.execute(plsql, new CallableStatementCallback() {
- @Override
- public String doInCallableStatement(final CallableStatement cs) throws SQLException {
- cs.setString(1, reporterId);
- cs.registerOutParameter(2, OracleTypes.CURSOR);
- cs.execute();
- final StringBuilder sb = new StringBuilder();
- final ResultSet rs = (ResultSet) cs.getObject(2);
- while (rs.next()) {
- final String text = rs.getString("text");
- if (text != null) {
- sb.append(text);
- sb.append('\n');
- }
+ return jdbcTemplate.execute(plsql, (CallableStatementCallback) cs -> {
+ cs.setString(1, reporterId);
+ cs.registerOutParameter(2, OracleTypes.CURSOR);
+ cs.execute();
+ final StringBuilder sb1 = new StringBuilder();
+ final ResultSet rs = (ResultSet) cs.getObject(2);
+ while (rs.next()) {
+ final String text = rs.getString("text");
+ if (text != null) {
+ sb1.append(text);
+ sb1.append('\n');
}
- rs.close();
- return sb.toString();
}
+ rs.close();
+ return sb1.toString();
});
}
@@ -231,6 +244,7 @@ private RealtimeReporterEvent convert(final String itemType, final String text)
}
}
+ @SuppressWarnings("DuplicatedCode")
private RealtimeReporterEvent convertToPreRunEvent(final Document doc) {
final PreRunEvent event = new PreRunEvent();
final Node totalNumberOfTestsNode = xmlTools.getNode(doc, "/event/totalNumberOfTests");
@@ -238,7 +252,7 @@ private RealtimeReporterEvent convertToPreRunEvent(final Document doc) {
if (totalNumberOfTestsNode != null) {
totalNumberOfTestsTextContent = totalNumberOfTestsNode.getTextContent();
}
- event.setTotalNumberOfTests(Integer.valueOf(totalNumberOfTestsTextContent));
+ event.setTotalNumberOfTests(Integer.valueOf(totalNumberOfTestsTextContent != null ? totalNumberOfTestsTextContent : "0"));
final NodeList nodes = xmlTools.getNodeList(doc, "/event/items/*");
for (int i = 0; i < nodes.getLength(); i++) {
final Node node = nodes.item(i);
@@ -311,6 +325,7 @@ private RealtimeReporterEvent convertToPostTestEvent(final Document doc) {
return event;
}
+ @SuppressWarnings("DuplicatedCode")
private void populate(final Suite suite, final Node node) {
if (node instanceof Element) {
suite.setId(xmlTools.getAttributeValue(node, "id"));
diff --git a/sqldev/src/main/java/org/utplsql/sqldev/menu/UtplsqlController.java b/sqldev/src/main/java/org/utplsql/sqldev/menu/UtplsqlController.java
index a7e74654..a4f59ba0 100644
--- a/sqldev/src/main/java/org/utplsql/sqldev/menu/UtplsqlController.java
+++ b/sqldev/src/main/java/org/utplsql/sqldev/menu/UtplsqlController.java
@@ -67,9 +67,11 @@ public class UtplsqlController implements Controller {
public static int UTPLSQL_TEST_CMD_ID = (Ide.findCmdID("utplsql.test")).intValue();
public static int UTPLSQL_COVERAGE_CMD_ID = (Ide.findCmdID("utplsql.coverage")).intValue();
+ public static int UTPLSQL_DEBUG_CMD_ID = (Ide.findCmdID("utplsql.debug")).intValue();
public static int UTPLSQL_GENERATE_CMD_ID = (Ide.findCmdID("utplsql.generate")).intValue();
public static final IdeAction UTPLSQL_TEST_ACTION = IdeAction.get(UTPLSQL_TEST_CMD_ID);
public static final IdeAction UTPLSQL_COVERAGE_ACTION = IdeAction.get(UTPLSQL_COVERAGE_CMD_ID);
+ public static final IdeAction UTPLSQL_DEBUG_ACTION = IdeAction.get(UTPLSQL_DEBUG_CMD_ID);
public static final IdeAction UTPLSQL_GENERATE_ACTION = IdeAction.get(UTPLSQL_GENERATE_CMD_ID);
@Override
@@ -77,12 +79,16 @@ public boolean handleEvent(final IdeAction action, final Context context) {
try {
if (action.getCommandId() == UTPLSQL_TEST_CMD_ID) {
logger.finer(() -> "handle utplsql.test");
- runTest(context);
+ runTest(context, false);
return true;
} else if (action.getCommandId() == UTPLSQL_COVERAGE_CMD_ID) {
logger.finer(() -> "handle utplsql.coverage");
codeCoverage(context);
return true;
+ } else if (action.getCommandId() == UTPLSQL_DEBUG_CMD_ID) {
+ logger.finer(() -> "handle utplsql.debug");
+ runTest(context, true);
+ return true;
} else if (action.getCommandId() == UTPLSQL_GENERATE_CMD_ID) {
logger.finer(() -> "handle utplsql.generate");
generateTest(context);
@@ -98,7 +104,8 @@ public boolean handleEvent(final IdeAction action, final Context context) {
@Override
public boolean update(final IdeAction action, final Context context) {
- if (action.getCommandId() == UTPLSQL_TEST_CMD_ID || action.getCommandId() == UTPLSQL_COVERAGE_CMD_ID) {
+ if (action.getCommandId() == UTPLSQL_TEST_CMD_ID || action.getCommandId() == UTPLSQL_COVERAGE_CMD_ID ||
+ action.getCommandId() == UTPLSQL_DEBUG_CMD_ID) {
final PreferenceModel preferences = PreferenceModel.getInstance(Preferences.getPreferences());
action.setEnabled(false);
final View view = context.getView();
@@ -315,7 +322,7 @@ private GenContext getGenContext(final Context context) {
return genContext;
}
- public void runTest(final Context context) {
+ public void runTest(final Context context, boolean withDebug) {
final View view = context.getView();
final Node node = context.getNode();
final PreferenceModel preferences = PreferenceModel.getInstance(Preferences.getPreferences());
@@ -348,9 +355,15 @@ public void runTest(final Context context) {
final RealtimeReporterDao rrDao = new RealtimeReporterDao(conn);
if (preferences.isUseRealtimeReporter() && rrDao.isSupported()) {
final UtplsqlRunner runner = new UtplsqlRunner(getPathList(path), connectionName);
+ if (withDebug) {
+ runner.enableDebugging();
+ }
runner.runTestAsync();
} else {
final UtplsqlWorksheetRunner worksheet = new UtplsqlWorksheetRunner(getPathList(path), connectionName);
+ if (withDebug) {
+ worksheet.enableDebugging();
+ }
worksheet.runTestAsync();
}
}
@@ -364,9 +377,15 @@ public void runTest(final Context context) {
final ArrayList pathList = dedupPathList(getPathList(context));
if (preferences.isUseRealtimeReporter() && rrDao.isSupported()) {
final UtplsqlRunner runner = new UtplsqlRunner(pathList, connectionName);
+ if (withDebug) {
+ runner.enableDebugging();
+ }
runner.runTestAsync();
} else {
final UtplsqlWorksheetRunner worksheet = new UtplsqlWorksheetRunner(pathList, connectionName);
+ if (withDebug) {
+ worksheet.enableDebugging();
+ }
worksheet.runTestAsync();
}
}
diff --git a/sqldev/src/main/java/org/utplsql/sqldev/model/DatabaseTools.java b/sqldev/src/main/java/org/utplsql/sqldev/model/DatabaseTools.java
index 9c2365ea..df12153b 100644
--- a/sqldev/src/main/java/org/utplsql/sqldev/model/DatabaseTools.java
+++ b/sqldev/src/main/java/org/utplsql/sqldev/model/DatabaseTools.java
@@ -104,22 +104,8 @@ public static String createTemporaryOrPrivateConnection(String connectionName) {
}
}
- public static boolean isConnectionClosed(Connection conn) {
- try {
- return conn.isClosed();
- } catch (SQLException e) {
- throw new GenericDatabaseAccessException("Error getting status of connection.", e);
- }
- }
-
public static void closeConnection(Connection conn) {
- if (!isConnectionClosed(conn)) {
- try {
- conn.close();
- } catch (SQLException e) {
- throw new GenericDatabaseAccessException("Could not close connection.");
- }
- }
+ abortConnection(conn);
}
public static void abortConnection(Connection conn) {
diff --git a/sqldev/src/main/java/org/utplsql/sqldev/model/runner/Counter.java b/sqldev/src/main/java/org/utplsql/sqldev/model/runner/Counter.java
index 77ffceb9..e14dc387 100644
--- a/sqldev/src/main/java/org/utplsql/sqldev/model/runner/Counter.java
+++ b/sqldev/src/main/java/org/utplsql/sqldev/model/runner/Counter.java
@@ -25,6 +25,14 @@ public class Counter {
private Integer error;
private Integer warning;
+ public Counter() {
+ disabled = 0;
+ success = 0;
+ failure = 0;
+ error = 0;
+ warning = 0;
+ }
+
@Override
public String toString() {
return new ToStringCreator(this, JsonToStringStyler.INSTANCE)
diff --git a/sqldev/src/main/java/org/utplsql/sqldev/model/runner/Item.java b/sqldev/src/main/java/org/utplsql/sqldev/model/runner/Item.java
index 70bcef0c..059102c5 100644
--- a/sqldev/src/main/java/org/utplsql/sqldev/model/runner/Item.java
+++ b/sqldev/src/main/java/org/utplsql/sqldev/model/runner/Item.java
@@ -28,6 +28,10 @@ public abstract class Item {
private String serverOutput;
private String warnings;
+ public Item() {
+ counter = new Counter();
+ }
+
@Override
public String toString() {
return new ToStringCreator(this, JsonToStringStyler.INSTANCE)
diff --git a/sqldev/src/main/java/org/utplsql/sqldev/model/runner/Run.java b/sqldev/src/main/java/org/utplsql/sqldev/model/runner/Run.java
index ed775d36..9d6b3358 100644
--- a/sqldev/src/main/java/org/utplsql/sqldev/model/runner/Run.java
+++ b/sqldev/src/main/java/org/utplsql/sqldev/model/runner/Run.java
@@ -15,12 +15,14 @@
*/
package org.utplsql.sqldev.model.runner;
+import java.sql.Connection;
import java.util.LinkedHashMap;
import java.util.List;
import org.springframework.core.style.ToStringCreator;
import org.utplsql.sqldev.model.JsonToStringStyler;
+@SuppressWarnings("unused")
public class Run {
private String reporterId;
private String connectionName;
@@ -38,6 +40,8 @@ public class Run {
private LinkedHashMap tests;
private String status;
private Long start;
+ // to abort connections, producerConn is handled by UtplsqlRunner
+ private Connection consumerConn;
@Override
public String toString() {
@@ -79,18 +83,13 @@ public void setStartTime(final String startTime) {
public String getName() {
final String time = startTime.substring(11, 19);
final String conn = connectionName != null ? connectionName.substring(15) : "n/a";
- final StringBuilder sb = new StringBuilder();
- sb.append(time);
- sb.append(" (");
- sb.append(conn);
- sb.append(")");
- return sb.toString();
+ return time + " (" + conn + ")";
}
public void put(final List- items) {
for (final Item item : items) {
if (item instanceof Test) {
- tests.put(((Test) item).getId(), (Test) item);
+ tests.put(item.getId(), (Test) item);
}
if (item instanceof Suite) {
put(((Suite) item).getItems());
@@ -107,7 +106,13 @@ public int getTotalNumberOfCompletedTests() {
|| counter.getError() == null) {
return -1;
}
- return counter.getDisabled() + counter.getSuccess() + counter.getFailure() + counter.getError();
+ int total = counter.getDisabled() + counter.getSuccess() + counter.getFailure() + counter.getError();
+ if (totalNumberOfTests != null && total > totalNumberOfTests) {
+ // can happen when run is cancelled and two processes are updating the run in parallel
+ // not worth to ensure consistency for this case, using synchronized will not be enough
+ total = totalNumberOfTests;
+ }
+ return total;
}
public String getReporterId() {
@@ -233,4 +238,12 @@ public Long getStart() {
public void setStart(final Long start) {
this.start = start;
}
+
+ public Connection getConsumerConn() {
+ return consumerConn;
+ }
+
+ public void setConsumerConn(Connection consumerConn) {
+ this.consumerConn = consumerConn;
+ }
}
diff --git a/sqldev/src/main/java/org/utplsql/sqldev/model/runner/Test.java b/sqldev/src/main/java/org/utplsql/sqldev/model/runner/Test.java
index 9e7d78ad..69338662 100644
--- a/sqldev/src/main/java/org/utplsql/sqldev/model/runner/Test.java
+++ b/sqldev/src/main/java/org/utplsql/sqldev/model/runner/Test.java
@@ -23,6 +23,7 @@
import org.utplsql.sqldev.model.JsonToStringStyler;
import org.utplsql.sqldev.resources.UtplsqlResources;
+@SuppressWarnings("unused")
public class Test extends Item {
private String executableType;
private String ownerName;
@@ -130,7 +131,7 @@ public void setProcedureName(final String procedureName) {
this.procedureName = procedureName;
}
- public Boolean getDisabled() {
+ public Boolean isDisabled() {
return disabled;
}
diff --git a/sqldev/src/main/java/org/utplsql/sqldev/runner/UtplsqlRunner.java b/sqldev/src/main/java/org/utplsql/sqldev/runner/UtplsqlRunner.java
index dbc62cb4..053e467c 100644
--- a/sqldev/src/main/java/org/utplsql/sqldev/runner/UtplsqlRunner.java
+++ b/sqldev/src/main/java/org/utplsql/sqldev/runner/UtplsqlRunner.java
@@ -19,7 +19,6 @@
import java.awt.Toolkit;
import java.sql.Connection;
import java.text.SimpleDateFormat;
-import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.UUID;
@@ -27,9 +26,14 @@
import javax.swing.JFrame;
+import oracle.dbtools.raptor.runner.DBStarterFactory;
+import oracle.ide.Context;
+import oracle.jdevimpl.runner.debug.DebuggingProcess;
+import oracle.jdevimpl.runner.run.JRunner;
import org.utplsql.sqldev.coverage.CodeCoverageReporter;
import org.utplsql.sqldev.dal.RealtimeReporterDao;
import org.utplsql.sqldev.dal.RealtimeReporterEventConsumer;
+import org.utplsql.sqldev.exception.GenericRuntimeException;
import org.utplsql.sqldev.model.DatabaseTools;
import org.utplsql.sqldev.model.SystemTools;
import org.utplsql.sqldev.model.runner.PostRunEvent;
@@ -48,12 +52,14 @@
public class UtplsqlRunner implements RealtimeReporterEventConsumer {
private static final Logger logger = Logger.getLogger(UtplsqlRunner.class.getName());
+ private static final int DEBUG_TIMEOUT_SECONDS = 60*60;
private final boolean withCodeCoverage;
private final List pathList;
private final List schemaList;
private final List includeObjectList;
private final List excludeObjectList;
+ private Context context;
private String connectionName;
private Connection producerConn;
private Connection consumerConn;
@@ -64,6 +70,7 @@ public class UtplsqlRunner implements RealtimeReporterEventConsumer {
private JFrame frame; // for testing purposes only (outside of SQL Developer)
private Thread producerThread;
private Thread consumerThread;
+ private boolean debug = false;
public UtplsqlRunner(final List pathList, final String connectionName) {
this.withCodeCoverage = false;
@@ -72,6 +79,7 @@ public UtplsqlRunner(final List pathList, final String connectionName) {
this.includeObjectList = null;
this.excludeObjectList = null;
setConnection(connectionName);
+ this.context = Context.newIdeContext();
}
public UtplsqlRunner(final List pathList, final List schemaList,
@@ -82,6 +90,7 @@ public UtplsqlRunner(final List pathList, final List schemaList,
this.includeObjectList = includeObjectList;
this.excludeObjectList = excludeObjectList;
setConnection(connectionName);
+ this.context = Context.newIdeContext();
}
/**
@@ -122,6 +131,10 @@ private void setConnection(final String connectionName) {
this.connectionName = connectionName;
}
+ public void enableDebugging() {
+ this.debug = true;
+ }
+
public void dispose() {
// running in SQL Developer
DatabaseTools.closeConnection(producerConn);
@@ -129,11 +142,13 @@ public void dispose() {
if (frame != null) {
frame.setVisible(false);
}
+ run.setConsumerConn(null);
}
+ @SuppressWarnings("StatementWithEmptyBody")
@Override
public void process(final RealtimeReporterEvent event) {
- logger.fine(() -> event.toString());
+ logger.fine(event::toString);
// dynamic dispatching code originally generated by Xtend
if (event instanceof PostRunEvent) {
doProcess((PostRunEvent) event);
@@ -144,15 +159,15 @@ public void process(final RealtimeReporterEvent event) {
} else if (event instanceof PreRunEvent) {
doProcess((PreRunEvent) event);
} else if (event instanceof PreSuiteEvent) {
- doProcess((PreSuiteEvent) event);
+ // not processed
} else if (event instanceof PreTestEvent) {
doProcess((PreTestEvent) event);
} else {
- throw new IllegalArgumentException("Unhandled parameter types: " + Arrays.asList(event).toString());
+ throw new IllegalArgumentException("Unhandled event: " + event.toString());
}
}
- private String getSysdate() {
+ public static String getSysdate() {
final Date dateTime = new Date(System.currentTimeMillis());
final SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'000'");
return df.format(dateTime);
@@ -170,6 +185,7 @@ private void initRun() {
run.setTotalNumberOfTests(-1);
run.setCurrentTestNumber(0);
run.setStatus(UtplsqlResources.getString("RUNNER_INITIALIZING_TEXT"));
+ run.setConsumerConn(consumerConn);
panel.setModel(run);
panel.update(realtimeReporterId);
}
@@ -187,14 +203,10 @@ private void doProcess(final PostRunEvent event) {
run.setExecutionTime(event.getExecutionTime());
run.setErrorStack(event.getErrorStack());
run.setServerOutput(event.getServerOutput());
- run.setStatus(UtplsqlResources.getString("RUNNER_FINNISHED_TEXT"));
+ run.setStatus(UtplsqlResources.getString("RUNNER_FINISHED_TEXT"));
panel.update(realtimeReporterId);
}
- private void doProcess(final PreSuiteEvent event) {
- // ignore
- }
-
private void doProcess(final PostSuiteEvent event) {
final Test test = run.getCurrentTest();
// Errors on suite levels are reported as warnings by the utPLSQL framework,
@@ -280,6 +292,19 @@ private void doProcess(final PostTestEvent event) {
panel.update(realtimeReporterId);
}
+ private void produceReportWithDebugger(String anonymousPlsqlBlock) {
+ try {
+ Context processContext = JRunner.prepareProcessContext(context, false);
+ DebuggingProcess process = new DebuggingProcess(processContext);
+ DBStarterFactory.PlSqlStarter starter = new DBStarterFactory.PlSqlStarter(process, anonymousPlsqlBlock, connectionName, context);
+ starter.start();
+ } catch (Throwable t) {
+ String msg = t.getClass().getName() + " while debugging utPLSQL test.";
+ logger.severe(() -> msg);
+ throw new GenericRuntimeException(msg);
+ }
+ }
+
private void produce() {
try {
logger.fine(() -> "Running utPLSQL tests and producing events via reporter id " + realtimeReporterId + "...");
@@ -287,38 +312,47 @@ private void produce() {
if (withCodeCoverage) {
dao.produceReportWithCoverage(realtimeReporterId, coverageReporterId, pathList, schemaList, includeObjectList, excludeObjectList);
} else {
- dao.produceReport(realtimeReporterId, pathList);
+ if (!debug) {
+ dao.produceReport(realtimeReporterId, pathList);
+ } else {
+ produceReportWithDebugger(dao.getProduceReportPlsql(realtimeReporterId, pathList));
+ }
}
logger.fine(() -> "All events produced for reporter id " + realtimeReporterId + ".");
} catch (Exception e) {
- logger.severe(() -> "Error while producing events for reporter id " + realtimeReporterId + ": "
- + (e != null ? e.getMessage() : "???"));
+ logger.severe(() -> "Error while producing events for reporter id " + realtimeReporterId + ": " + e.getMessage() + ".");
}
}
private void consume() {
try {
- logger.fine(() -> "Consuming events from reporter id " + realtimeReporterId + " in realtime...");
- final RealtimeReporterDao dao = new RealtimeReporterDao(consumerConn);
- dao.consumeReport(realtimeReporterId, this);
- logger.fine(() -> "All events consumed.");
- if (withCodeCoverage) {
- String html = dao.getHtmlCoverage(coverageReporterId);
- CodeCoverageReporter.openInBrowser(html);
+ try {
+ logger.fine(() -> "Consuming events from reporter id " + realtimeReporterId + " in realtime...");
+ final RealtimeReporterDao dao = new RealtimeReporterDao(consumerConn);
+ if (!debug) {
+ dao.consumeReport(realtimeReporterId, this);
+ } else {
+ dao.consumeReport(realtimeReporterId, this, DEBUG_TIMEOUT_SECONDS);
+ }
+ logger.fine(() -> "All events consumed.");
+ if (withCodeCoverage) {
+ String html = dao.getHtmlCoverage(coverageReporterId);
+ CodeCoverageReporter.openInBrowser(html);
+ }
+ } catch (Exception e) {
+ logger.severe(() -> "Error while consuming events for reporter id " + realtimeReporterId + ": " + e.getMessage() + ".");
+ }
+ } finally {
+ if (run.getTotalNumberOfTests() < 0) {
+ run.setStatus(UtplsqlResources.getString("RUNNER_NO_TESTS_FOUND_TEXT"));
+ run.setExecutionTime((System.currentTimeMillis() - Double.valueOf(run.getStart())) / 1000);
+ run.setEndTime(getSysdate());
+ run.setTotalNumberOfTests(0);
+ panel.update(realtimeReporterId);
+ }
+ if (isRunningInSqlDeveloper()) {
+ dispose();
}
- } catch (Exception e) {
- logger.severe(() -> "Error while consuming events for reporter id " + realtimeReporterId + ": "
- + (e != null ? e.getMessage() : "???"));
- }
- if (run.getTotalNumberOfTests() < 0) {
- run.setStatus(UtplsqlResources.getString("RUNNER_NO_TESTS_FOUND_TEXT"));
- run.setExecutionTime(Double.valueOf(System.currentTimeMillis() - Double.valueOf(run.getStart())) / 1000);
- run.setEndTime(getSysdate());
- run.setTotalNumberOfTests(0);
- panel.update(realtimeReporterId);
- }
- if (isRunningInSqlDeveloper()) {
- dispose();
}
}
@@ -332,9 +366,10 @@ private boolean initGUI() {
logger.severe(() -> "Error getting utPLSQL dockable. Cannot run utPLSQL test.");
return false;
} else {
- if (isRunningInSqlDeveloper() && dockable != null) {
+ if (isRunningInSqlDeveloper()) {
RunnerFactory.showDockable();
panel = dockable.getRunnerPanel();
+ context.setView(dockable);
} else {
frame = new JFrame("utPLSQL Runner Panel");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
@@ -356,13 +391,13 @@ public void runTestAsync() {
// start tests when the GUI has been successfully initialized.
if (initGUI()) {
// the consumer
- consumerThread = new Thread(() -> consume());
+ consumerThread = new Thread(this::consume);
consumerThread.setName("realtime consumer");
consumerThread.start();
// avoid concurrency on output header table to fix issue #80
SystemTools.sleep(100);
// the producer
- producerThread = new Thread(() -> produce());
+ producerThread = new Thread(this::produce);
producerThread.setName("realtime producer");
producerThread.start();
}
diff --git a/sqldev/src/main/java/org/utplsql/sqldev/runner/UtplsqlWorksheetRunner.java b/sqldev/src/main/java/org/utplsql/sqldev/runner/UtplsqlWorksheetRunner.java
index b56b06fa..ebc0e7cc 100644
--- a/sqldev/src/main/java/org/utplsql/sqldev/runner/UtplsqlWorksheetRunner.java
+++ b/sqldev/src/main/java/org/utplsql/sqldev/runner/UtplsqlWorksheetRunner.java
@@ -21,7 +21,12 @@
import javax.swing.JSplitPane;
+import oracle.dbtools.raptor.runner.DBStarterFactory;
+import oracle.ide.Context;
+import oracle.jdevimpl.runner.debug.DebuggingProcess;
+import oracle.jdevimpl.runner.run.JRunner;
import org.utplsql.sqldev.exception.GenericDatabaseAccessException;
+import org.utplsql.sqldev.exception.GenericRuntimeException;
import org.utplsql.sqldev.model.DatabaseTools;
import org.utplsql.sqldev.model.StringTools;
import org.utplsql.sqldev.model.SystemTools;
@@ -39,9 +44,10 @@
public class UtplsqlWorksheetRunner {
private static final Logger logger = Logger.getLogger(UtplsqlWorksheetRunner.class.getName());
- private PreferenceModel preferences;
+ private final PreferenceModel preferences;
+ private final List pathList;
private String connectionName;
- private List pathList;
+ private boolean debug = false;
public UtplsqlWorksheetRunner(final List pathList, final String connectionName) {
this.pathList = pathList;
@@ -49,6 +55,10 @@ public UtplsqlWorksheetRunner(final List pathList, final String connecti
setConnection(connectionName);
}
+ public void enableDebugging() {
+ this.debug = true;
+ }
+
private void setConnection(final String connectionName) {
if (connectionName != null && preferences.isUnsharedWorksheet()) {
try {
@@ -65,23 +75,32 @@ private void setConnection(final String connectionName) {
private CharSequence getCode() {
StringBuilder sb = new StringBuilder();
- if (preferences.isResetPackage()) {
- sb.append("EXECUTE dbms_session.reset_package;\n");
- }
- sb.append("SET SERVEROUTPUT ON SIZE UNLIMITED\n");
- if (preferences.isClearScreen()) {
- sb.append("CLEAR SCREEN\n");
- }
- final List paths = pathList;
- if (paths.size() == 1) {
- sb.append("EXECUTE ut.run('");
- sb.append(paths.get(0));
- sb.append("');\n");
+ if (!debug) {
+ if (preferences.isResetPackage()) {
+ sb.append("EXECUTE dbms_session.reset_package;\n");
+ }
+ sb.append("SET SERVEROUTPUT ON SIZE UNLIMITED\n");
+ if (preferences.isClearScreen()) {
+ sb.append("CLEAR SCREEN\n");
+ }
+ if (pathList.size() == 1) {
+ sb.append("EXECUTE ut.run('");
+ sb.append(pathList.get(0));
+ sb.append("');\n");
+ } else {
+ // we want a horizontal dense output because we resize the worksheet to fit the command in common cases
+ sb.append("EXECUTE ut.run(ut_varchar2_list(");
+ sb.append(StringTools.getCSV(pathList, "").replace("\n", ""));
+ sb.append("));\n");
+ }
} else {
- // we want a horizontal dense output because we resize the worksheet to fit the command in common cases
- sb.append("EXECUTE ut.run(ut_varchar2_list(");
- sb.append(StringTools.getCSV(pathList, "").replace("\n",""));
- sb.append("));\n");
+ sb.append("BEGIN\n");
+ sb.append(" ut.run(\n");
+ sb.append(" ut_varchar2_list(\n");
+ sb.append(StringTools.getCSV(pathList, 9));
+ sb.append(" )\n");
+ sb.append(" );\n");
+ sb.append("END;\n");
}
return sb;
}
@@ -115,17 +134,37 @@ private void resizeResultPanel(final Worksheet worksheet) {
}
}
+ // cannot use IdeAction to run debugger, because text has to be set in inaccessible PLSQLController.updateAction
+ private void runDebugger(final Worksheet worksheet, final String anonymousPlsqlBlock) {
+ try {
+ Context processContext = JRunner.prepareProcessContext(worksheet.getContext(), false);
+ DebuggingProcess process = new DebuggingProcess(processContext);
+ DBStarterFactory.PlSqlStarter starter = new DBStarterFactory.PlSqlStarter(process, anonymousPlsqlBlock, connectionName, worksheet.getContext());
+ starter.start();
+ } catch (Throwable t) {
+ String msg = t.getClass().getName() + " while debugging utPLSQL test.";
+ logger.severe(() -> msg);
+ throw new GenericRuntimeException(msg);
+ }
+ }
+
private void runScript(final Worksheet worksheet) {
if (preferences.isAutoExecute()) {
SystemTools.sleep(100);
- final IdeAction action = ((IdeAction) Ide.getIdeActionMap().get(Ide.findCmdID("Worksheet.RunScript")));
- if (action != null) {
- try {
- action.performAction(worksheet.getContext());
- } catch (Exception e) {
- logger.severe(() -> "Could not run script in worksheet due to " + (e != null ? e.getMessage() : "???") + ".");
+ if (debug) {
+ runDebugger(worksheet, worksheet.getFocusedEditorPane().getText());
+ } else {
+ final IdeAction action = ((IdeAction) Ide.getIdeActionMap().get(Ide.findCmdID("Worksheet.RunScript")));
+ if (action != null) {
+ try {
+ action.performAction(worksheet.getContext());
+ } catch (Exception e) {
+ logger.severe(() -> "Could not run script in worksheet due to " + e.getMessage() + ".");
+ }
+ if (!debug) {
+ resizeResultPanel(worksheet);
+ }
}
- resizeResultPanel(worksheet);
}
}
}
@@ -137,7 +176,7 @@ private void runTest() {
}
public void runTestAsync() {
- final Thread thread = new Thread(() -> runTest());
+ final Thread thread = new Thread(this::runTest);
thread.setName("utPLSQL run test");
thread.start();
}
diff --git a/sqldev/src/main/java/org/utplsql/sqldev/ui/runner/RunnerPanel.java b/sqldev/src/main/java/org/utplsql/sqldev/ui/runner/RunnerPanel.java
index a7650ea1..b9f2bdd3 100644
--- a/sqldev/src/main/java/org/utplsql/sqldev/ui/runner/RunnerPanel.java
+++ b/sqldev/src/main/java/org/utplsql/sqldev/ui/runner/RunnerPanel.java
@@ -54,7 +54,6 @@
import javax.swing.LookAndFeel;
import javax.swing.RepaintManager;
import javax.swing.RowFilter;
-import javax.swing.SwingConstants;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.border.Border;
@@ -100,6 +99,7 @@ public class RunnerPanel {
private Run currentRun;
private JPanel basePanel;
private DefaultComboBoxModel> runComboBoxModel;
+ private ToolbarButton stopButton;
private JComboBox> runComboBox;
private JLabel statusLabel;
private Timer elapsedTimeTimer;
@@ -117,6 +117,7 @@ public class RunnerPanel {
private JTable testOverviewTable;
private JMenuItem testOverviewRunMenuItem;
private JMenuItem testOverviewRunWorksheetMenuItem;
+ private JMenuItem testOverviewDebugMenuItem;
private JMenuItem testOverviewCodeCoverageMenuItem;
private JCheckBoxMenuItem showTestDescriptionCheckBoxMenuItem;
private JCheckBoxMenuItem showWarningIndicatorCheckBoxMenuItem;
@@ -139,7 +140,7 @@ public class RunnerPanel {
private JTabbedPane testDetailTabbedPane;
// used in multiple components, therefore an inner class
- private class TestTableHeaderRenderer extends DefaultTableCellRenderer {
+ private static class TestTableHeaderRenderer extends DefaultTableCellRenderer {
private static final long serialVersionUID = 6295858563570577027L;
@Override
@@ -168,8 +169,8 @@ public Component getTableCellRendererComponent(final JTable table, final Object
}
}
- // used in mulitple components, therefore an inner class
- private class FailuresTableHeaderRenderer extends DefaultTableCellRenderer {
+ // used in multiple components, therefore an inner class
+ private static class FailuresTableHeaderRenderer extends DefaultTableCellRenderer {
private static final long serialVersionUID = 5059401447983514596L;
@Override
@@ -201,6 +202,7 @@ private void resetDerived() {
testOverviewTable.getRowSorter().setSortKeys(null);
testOverviewRunMenuItem.setEnabled(false);
testOverviewRunWorksheetMenuItem.setEnabled(false);
+ testOverviewDebugMenuItem.setEnabled(false);
testOverviewCodeCoverageMenuItem.setEnabled(false);
testIdTextArea.setText(null);
testOwnerTextField.setText(null);
@@ -214,6 +216,7 @@ private void resetDerived() {
testErrorStackTextPane.setText(null);
testWarningsTextPane.setText(null);
testServerOutputTextPane.setText(null);
+ enableOrDisableStopButton();
}
private void refreshRunsComboBox() {
@@ -262,8 +265,7 @@ private void applyShowTestDescription() {
testOverviewTable.getTableHeader().repaint();
}
- private void applyShowWarningIndicator(final boolean show) {
- final TableColumn col = testOverviewTable.getColumnModel().getColumn(1);
+ private void showColumn(final boolean show, TableColumn col) {
if (show) {
col.setWidth(INDICATOR_WIDTH);
col.setMinWidth(INDICATOR_WIDTH);
@@ -277,25 +279,19 @@ private void applyShowWarningIndicator(final boolean show) {
}
}
+ private void applyShowWarningIndicator(final boolean show) {
+ showColumn(show, testOverviewTable.getColumnModel().getColumn(1));
+ }
+
private void applyShowInfoIndicator(final boolean show) {
- final TableColumn col = testOverviewTable.getColumnModel().getColumn(2);
- if (show) {
- col.setWidth(INDICATOR_WIDTH);
- col.setMinWidth(INDICATOR_WIDTH);
- col.setMaxWidth(INDICATOR_WIDTH);
- col.setPreferredWidth(INDICATOR_WIDTH);
- } else {
- col.setWidth(0);
- col.setMinWidth(0);
- col.setMaxWidth(0);
- col.setPreferredWidth(0);
- }
+ showColumn(show, testOverviewTable.getColumnModel().getColumn(2));
}
private void applyFilter(final boolean showSuccessfulTests, final boolean showDisabledTests) {
@SuppressWarnings("unchecked")
final TableRowSorter sorter = ((TableRowSorter) testOverviewTable.getRowSorter());
final RowFilter filter = new RowFilter() {
+ @SuppressWarnings("RedundantIfStatement")
@Override
public boolean include(final RowFilter.Entry extends TestOverviewTableModel, ? extends Integer> entry) {
final Test test = entry.getModel().getTest((entry.getIdentifier()).intValue());
@@ -348,6 +344,7 @@ private void openSelectedFailure() {
}
}
+ @SuppressWarnings("StringBufferReplaceableByString")
private String getHtml(final String text) {
StringBuilder sb = new StringBuilder();
sb.append("\n");
@@ -384,6 +381,7 @@ private void openLink(final String link) {
openEditor(ownerName, objectType, objectName.toUpperCase(), line, 1);
}
+ @SuppressWarnings("SameParameterValue")
private void openEditor(final String owner, final String type, final String name, final int line, final int col) {
DefaultDrillLink drillLink = new DefaultDrillLink();
drillLink.setConnName(currentRun.getConnectionName());
@@ -417,14 +415,12 @@ private void syncDetailTab() {
}
private PreferenceModel getPreferenceModel() {
- PreferenceModel preferences = null;
try {
- preferences = PreferenceModel.getInstance(Preferences.getPreferences());
+ return PreferenceModel.getInstance(Preferences.getPreferences());
} catch (NoClassDefFoundError e) {
// running outside of SQL Developer
- preferences = PreferenceModel.getInstance(null);
+ return PreferenceModel.getInstance(null);
}
- return preferences;
}
private void applyPreferences() {
@@ -483,7 +479,23 @@ private void setCurrentRun(final Run run) {
}
}
+ private void showDockable() {
+ try {
+ if (!RunnerFactory.getDockable().isVisible()) {
+ RunnerFactory.showDockable();
+ }
+ } catch (Throwable t) {
+ // ignore
+ }
+ }
+
+ private void enableOrDisableStopButton() {
+ stopButton.setEnabled(currentRun.getEndTime() == null);
+ }
+
public synchronized void update(final String reporterId) {
+ showDockable();
+ enableOrDisableStopButton();
setCurrentRun(runs.get(reporterId));
final int row = currentRun.getCurrentTestNumber() - 1;
final CharSequence header = testOverviewTableModel.getTestIdColumnName();
@@ -568,9 +580,11 @@ private void comboBoxAction() {
@SuppressWarnings("unchecked")
final ComboBoxItem comboBoxItem = (ComboBoxItem) runComboBox
.getSelectedItem();
- if (currentRun.getReporterId() != null && !currentRun.getReporterId().equals(comboBoxItem.getKey())) {
- update(comboBoxItem.getKey());
- testDetailTabbedPane.setSelectedIndex(0);
+ if (currentRun.getReporterId() != null && comboBoxItem != null) {
+ if (!currentRun.getReporterId().equals(comboBoxItem.getKey())) {
+ update(comboBoxItem.getKey());
+ testDetailTabbedPane.setSelectedIndex(0);
+ }
}
}
}
@@ -695,6 +709,7 @@ private void runCodeCoverage(boolean selectedOnly) {
reporter.showParameterWindow();
}
+ @SuppressWarnings("DuplicatedCode")
private void initializeGUI() {
// Base panel containing all components
basePanel = new JPanel();
@@ -731,11 +746,70 @@ private void initializeGUI() {
worksheet.runTestAsync();
});
toolbar.add(rerunWorksheetButton);
+ final ToolbarButton debugButton = new ToolbarButton(UtplsqlResources.getIcon("DEBUG_ICON"));
+ debugButton.setToolTipText(UtplsqlResources.getString("RUNNER_DEBUG_TOOLTIP"));
+ debugButton.setBorder(buttonBorder);
+ debugButton.addActionListener(event -> {
+ final UtplsqlRunner runner = new UtplsqlRunner(currentRun.getPathList(), currentRun.getConnectionName());
+ runner.enableDebugging();
+ runner.runTestAsync();
+ });
+ toolbar.add(debugButton);
final ToolbarButton codeCoverageButton = new ToolbarButton(UtplsqlResources.getIcon("CODE_COVERAGE_ICON"));
codeCoverageButton.setToolTipText(UtplsqlResources.getString("RUNNER_CODE_COVERAGE_TOOLTIP"));
codeCoverageButton.setBorder(buttonBorder);
codeCoverageButton.addActionListener(event -> runCodeCoverage(false));
toolbar.add(codeCoverageButton);
+ stopButton = new ToolbarButton(UtplsqlResources.getIcon("STOP_ICON"));
+ stopButton.setToolTipText(UtplsqlResources.getString("RUNNER_STOP_TOOLTIP"));
+ stopButton.setBorder(buttonBorder);
+ stopButton.addActionListener(event -> {
+ if (currentRun.getConsumerConn() != null) {
+ // Aborts JDBC Connection. Connection might still run in the background. That's expected.
+ DatabaseTools.abortConnection(currentRun.getConsumerConn());
+ for (Test test : currentRun.getTests().values()) {
+ if (test.getEndTime() == null && !test.isDisabled()) {
+ test.setDisabled(true);
+ test.getCounter().setDisabled(1);
+ test.getCounter().setWarning(1);
+ test.setWarnings(UtplsqlResources.getString("RUNNER_STOP_TEST_MESSAGE"));
+ test.setStartTime(null);
+ }
+ }
+ // recalculate counters and fix inconsistencies
+ currentRun.getCounter().setSuccess(0);
+ currentRun.getCounter().setFailure(0);
+ currentRun.getCounter().setError(0);
+ currentRun.getCounter().setDisabled(0);
+ currentRun.getCounter().setWarning(0);
+ for (Test test : currentRun.getTests().values()) {
+ if (test.isDisabled() && test.getCounter().getDisabled() == 0) {
+ test.getCounter().setDisabled(1);
+ }
+ if (test.getFailedExpectations() != null && !test.getFailedExpectations().isEmpty() && test.getCounter().getFailure() == 0) {
+ test.getCounter().setFailure(1);
+ }
+ if (test.getErrorStack() != null && test.getCounter().getError() == 0) {
+ test.getCounter().setError(1);
+ }
+ currentRun.getCounter().setSuccess(currentRun.getCounter().getSuccess() + test.getCounter().getSuccess());
+ currentRun.getCounter().setFailure(currentRun.getCounter().getFailure() + test.getCounter().getFailure());
+ currentRun.getCounter().setError(currentRun.getCounter().getError() + test.getCounter().getError());
+ currentRun.getCounter().setDisabled(currentRun.getCounter().getDisabled() + test.getCounter().getDisabled());
+ currentRun.getCounter().setWarning(currentRun.getCounter().getWarning() + test.getCounter().getWarning());
+ }
+ // terminate run
+ currentRun.setEndTime(UtplsqlRunner.getSysdate());
+ double now = (double) System.currentTimeMillis();
+ currentRun.setExecutionTime((now - currentRun.getStart()) / 1000);
+ currentRun.setCurrentTestNumber(0);
+ currentRun.setStatus(UtplsqlResources.getString("RUNNER_STOP_RUN_MESSAGE"));
+ // update run in GUI
+ update(currentRun.getReporterId());
+ }
+ });
+ stopButton.setEnabled(false);
+ toolbar.add(stopButton);
toolbar.add(Box.createHorizontalGlue());
runComboBoxModel = new DefaultComboBoxModel<>();
runComboBox = new JComboBox<>(runComboBoxModel);
@@ -798,8 +872,8 @@ private void initializeGUI() {
time.setSeconds(currentRun.getExecutionTime());
elapsedTimeTimer.stop();
} else {
- final Double now = Double.valueOf(System.currentTimeMillis());
- time.setSeconds(Double.valueOf(now - currentRun.getStart()) / 1000);
+ final Double now = (double) System.currentTimeMillis();
+ time.setSeconds((now - currentRun.getStart()) / 1000);
}
elapsedTimeLabel.setText(time.toString() + (!useSmartTimes ? " s" : ""));
} else {
@@ -925,6 +999,7 @@ private void initializeGUI() {
syncDetailTab();
testOverviewRunMenuItem.setEnabled(true);
testOverviewRunWorksheetMenuItem.setEnabled(true);
+ testOverviewDebugMenuItem.setEnabled(true);
testOverviewCodeCoverageMenuItem.setEnabled(true);
}
});
@@ -982,8 +1057,7 @@ public Component getTableCellRendererComponent(final JTable table, final Object
final JPopupMenu testOverviewPopupMenu = new JPopupMenu();
testOverviewRunMenuItem = new JMenuItem(UtplsqlResources.getString("RUNNER_RUN_MENUITEM"), UtplsqlResources.getIcon("RUN_ICON"));
testOverviewRunMenuItem.addActionListener(event -> {
- final UtplsqlRunner runner = new UtplsqlRunner(getPathListFromSelectedTests(),
- currentRun.getConnectionName());
+ final UtplsqlRunner runner = new UtplsqlRunner(getPathListFromSelectedTests(), currentRun.getConnectionName());
runner.runTestAsync();
});
testOverviewPopupMenu.add(testOverviewRunMenuItem);
@@ -994,6 +1068,13 @@ public Component getTableCellRendererComponent(final JTable table, final Object
worksheet.runTestAsync();
});
testOverviewPopupMenu.add(testOverviewRunWorksheetMenuItem);
+ testOverviewDebugMenuItem = new JMenuItem(UtplsqlResources.getString("MENU_DEBUG_TEST_LABEL"), UtplsqlResources.getIcon("DEBUG_ICON"));
+ testOverviewDebugMenuItem.addActionListener(event -> {
+ final UtplsqlRunner runner = new UtplsqlRunner(getPathListFromSelectedTests(), currentRun.getConnectionName());
+ runner.enableDebugging();
+ runner.runTestAsync();
+ });
+ testOverviewPopupMenu.add(testOverviewDebugMenuItem);
testOverviewCodeCoverageMenuItem = new JMenuItem(UtplsqlResources.getString("MENU_CODE_COVERAGE_LABEL"), UtplsqlResources.getIcon("CODE_COVERAGE_ICON"));
testOverviewCodeCoverageMenuItem.addActionListener(event -> runCodeCoverage(true));
testOverviewPopupMenu.add(testOverviewCodeCoverageMenuItem);
@@ -1262,7 +1343,7 @@ public void mouseClicked(final MouseEvent e) {
c.weighty = 6;
// - split pane
- final JSplitPane failuresSplitPane = new JSplitPane(SwingConstants.HORIZONTAL, failuresTableScrollPane,
+ final JSplitPane failuresSplitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, failuresTableScrollPane,
testFailureMessageScrollPane);
failuresSplitPane.setResizeWeight(0.2);
@@ -1344,7 +1425,7 @@ public void mouseClicked(final MouseEvent e) {
testDetailTabbedPane.add(UtplsqlResources.getString("RUNNER_ERRORS_TAB_LABEL"), testErrorStackPanel);
testDetailTabbedPane.add(UtplsqlResources.getString("RUNNER_WARNINGS_TAB_LABEL"), testWarningsPanel);
testDetailTabbedPane.add(UtplsqlResources.getString("RUNNER_INFO_TAB_LABEL"), testServerOutputPanel);
- final JSplitPane horizontalSplitPane = new JSplitPane(SwingConstants.HORIZONTAL, testOverviewScrollPane,
+ final JSplitPane horizontalSplitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, testOverviewScrollPane,
testDetailTabbedPane);
horizontalSplitPane.setResizeWeight(0.5);
c.gridx = 0;
diff --git a/sqldev/src/main/resources/org/utplsql/sqldev/resources/UtplsqlResources.properties b/sqldev/src/main/resources/org/utplsql/sqldev/resources/UtplsqlResources.properties
index 141984bf..71b79deb 100644
--- a/sqldev/src/main/resources/org/utplsql/sqldev/resources/UtplsqlResources.properties
+++ b/sqldev/src/main/resources/org/utplsql/sqldev/resources/UtplsqlResources.properties
@@ -1,108 +1,118 @@
-# English (default) resources for extension org.utplsql.sqldev
-
-# Externally used constants (pom.xml, bundle.xml, extension.xml, sqldeveloper.xml)
-EXTENSION_NAME=utPLSQL for SQL Developer
-EXTENSION_DESCRIPTION=Extension for running unit tests in SQL Developer.
-EXTENSION_OWNER=Philipp Salvisberg
-MIN_SQLDEV_VERSION=12.2.0.19.0.7
-
-# Icons
-UTPLSQL_ICON=/org/utplsql/sqldev/resources/images/utPLSQL.png
-SUCCESS_ICON=/org/utplsql/sqldev/resources/images/success.png
-ERROR_ICON=/org/utplsql/sqldev/resources/images/error.png
-FAILURE_ICON=/org/utplsql/sqldev/resources/images/failure.png
-DISABLED_ICON=/org/utplsql/sqldev/resources/images/disabled.png
-WARNING_ICON=/org/utplsql/sqldev/resources/images/warning.png
-INFO_ICON=/org/utplsql/sqldev/resources/images/info.png
-REFRESH_ICON=/org/utplsql/sqldev/resources/images/refresh.png
-RUN_ICON=/org/utplsql/sqldev/resources/images/run.png
-RUN_WORKSHEET_ICON=/org/utplsql/sqldev/resources/images/run_worksheet.png
-CLEAR_ICON=/org/utplsql/sqldev/resources/images/clear.png
-CHECKMARK_ICON=/org/utplsql/sqldev/resources/images/checkmark.png
-STATUS_ICON=/org/utplsql/sqldev/resources/images/status.png
-# progress.gif - the animated version - does not work
-PROGRESS_ICON=/org/utplsql/sqldev/resources/images/progress.png
-CODE_COVERAGE_ICON=/org/utplsql/sqldev/resources/images/coverage.png
-
-# Translatable text
-PREF_LABEL=utPLSQL
-PREF_USE_REALTIME_REPORTER_LABEL=Use realtime reporter?
-PREF_USE_REALTIME_REPORTER_HINT=Requires utPLSQL v3.1.4 or later. Opens a worksheet for older versions.
-PREF_UNSHARED_WORKSHEET_LABEL=Open an unshared worksheet?
-PREF_RESET_PACKAGE_LABEL=Reset package before running utPLSQL?
-PREF_CLEAR_SCREEN_LABEL=Clear script output panel before running utPLSQL?
-PREF_AUTO_EXECUTE_LABEL=Execute unit test automatically?
-PREF_CHECK_RUN_UTPLSQL_TEST_LABEL=Check availability of menu option?
-PREF_USE_SMART_TIMES_LABEL=Use smart times?
-PREF_IMPORT_SNIPPETS_BUTTON_LABEL=Import Snippets
-MENU_REALTIME_REPORTER_LABEL=Realtime Reporter
-PREF_NUMBER_OF_RUNS_IN_HISTORY_LABEL=Number of runs in history
-PREF_SHOW_DISABLED_COUNTER_LABEL=Show disabled counter?
-PREF_SHOW_WARNINGS_COUNTER_LABEL=Show warnings counter?
-PREF_SHOW_INFO_COUNTER_LABEL=Show info counter?
-PREF_SHOW_WARNING_INDICATOR_LABEL=Show warning indicator?
-PREF_SHOW_INFO_INDICATOR_LABEL=Show info indicator?
-PREF_SHOW_SUCCESSFUL_TESTS_LABEL=Show successful tests?
-PREF_SHOW_DISABLED_TESTS_LABEL=Show disabled tests?
-PREF_SHOW_TEST_DESCRIPTION_LABEL=Show description (if present)?
-PREF_SYNC_DETAIL_TAB_LABEL=Synchronize detail tab based on test status?
-PREF_TEST_PACKAGE_PREFIX_LABEL=Test package prefix
-PREF_TEST_PACKAGE_SUFFIX_LABEL=Test package suffix
-PREF_TEST_UNIT_PREFIX_LABEL=Test unit prefix
-PREF_TEST_UNIT_SUFFIX_LABEL=Test unit suffix
-PREF_NUMBER_OF_TESTS_PER_UNIT_LABEL=Number of tests to generate per unit
-PREF_GENERATE_COMMENTS_LABEL=Generate comments?
-PREF_DISABLE_TESTS_LABEL=Disable tests?
-PREF_SUITE_PATH_LABEL=Suite path
-PREF_INDENT_SPACES_LABEL=Indent spaces
-PREF_CHECK_GENERATE_UTPLSQL_TEST_LABEL=Check availability of menu option?
-PREF_CREATE_CODE_TEMPLATES_BUTTON_LABEL=Create code templates
-PREF_ROOT_FOLDER_IN_ODDGEN_VIEW_LABEL=Root folder in Generators view
-PREF_GENERATE_FILES_LABEL=Generate files?
-PREF_OUTPUT_DIRECTORY_LABEL=Output directory
-PREF_OUTPUT_DIRECTORY_BUTTON_LABEL=Browse
-PREF_DELETE_EXISTING_FILES_LABEL=Delete existing files in output directory?
-PREF_CONFIRM_IMPORT_TITLE=Snippets imported
-PREF_CONFIRM_IMPORT_MESSAGE=Snippets imported into %s. Please restart SQL Developer for this change to take effect.
-MENU_RUN_TEST_LABEL=Run utPLSQL test
-MENU_CODE_COVERAGE_LABEL=Code coverage...
-MENU_GENERATE_TEST_LABEL=Generate utPLSQL test
-WINDOW_CODE_COVERAGE_REPORT_LABEL=Code coverage report
-WINDOW_PATHS_LABEL=utPLSQL paths
-WINDOW_SCHEMAS_LABEL=Schemas under test
-WINDOW_INCLUDE_OBJECS_LABEL=Include objects
-WINDOW_EXCLUDE_OBJECS_LABEL=Exclude objects
-WINDOW_RUN_BUTTON=Run
-WINDOW_CANCEL_BUTTON=Cancel
-WORKSHEET_TITLE=utPLSQL
-RUNNER_VIEW_TITLE=utPLSQL
-RUNNER_REFRESH_TOOLTIP=Reset ordering and refresh
-RUNNER_RERUN_TOOLTIP=Rerun all tests
-RUNNER_CLEAR_BUTTON=Clear run history
-RUNNER_RERUN_WORKSHEET_TOOLTIP=Rerun all tests in a new worksheet
-RUNNER_CODE_COVERAGE_TOOLTIP=Rerun all tests with code coverage
-RUNNER_TESTS_LABEL=Tests
-RUNNER_FAILURES_LABEL=Failures
-RUNNER_ERRORS_LABEL=Errors
-RUNNER_DISABLED_LABEL=Disabled
-RUNNER_WARNINGS_LABEL=Warnings
-RUNNER_INFO_LABEL=Info
-RUNNER_INITIALIZING_TEXT=Initializing...
-RUNNER_RUNNING_TEXT=Running tests...
-RUNNER_FINNISHED_TEXT=Finished.
-RUNNER_NO_TESTS_FOUND_TEXT=No tests found.
-RUNNER_RUN_MENUITEM=Run test
-RUNNER_RUN_WORKSHEET_MENUITEM=Run test in new worksheet
-RUNNER_TEST_ID_COLUMN=Suitepath
-RUNNER_TEST_EXECUTION_TIME_COLUMN=Time
-RUNNER_OWNER_LABEL=Owner
-RUNNER_PACKAGE_LABEL=Package
-RUNNER_PROCEDURE_LABEL=Procedure
-RUNNER_DESCRIPTION_LABEL=Description
-RUNNER_START_LABEL=Start
-RUNNER_ASSERT_DESCRIPTION_COLUMN=Assert description (failed line)
-RUNNER_TEST_TAB_LABEL=Test
-RUNNER_FAILURES_TAB_LABEL=Failures
-RUNNER_ERRORS_TAB_LABEL=Errors
-RUNNER_WARNINGS_TAB_LABEL=Warnings
-RUNNER_INFO_TAB_LABEL=Info
+# English (default) resources for extension org.utplsql.sqldev
+
+# Externally used constants (pom.xml, bundle.xml, extension.xml, sqldeveloper.xml)
+EXTENSION_NAME=utPLSQL for SQL Developer
+# suppress inspection "UnusedProperty"
+EXTENSION_DESCRIPTION=Extension for running unit tests in SQL Developer.
+EXTENSION_OWNER=Philipp Salvisberg
+# suppress inspection "UnusedProperty"
+MIN_SQLDEV_VERSION=12.2.0.19.0.7
+
+# Icons
+UTPLSQL_ICON=/org/utplsql/sqldev/resources/images/utPLSQL.png
+SUCCESS_ICON=/org/utplsql/sqldev/resources/images/success.png
+ERROR_ICON=/org/utplsql/sqldev/resources/images/error.png
+FAILURE_ICON=/org/utplsql/sqldev/resources/images/failure.png
+DISABLED_ICON=/org/utplsql/sqldev/resources/images/disabled.png
+WARNING_ICON=/org/utplsql/sqldev/resources/images/warning.png
+INFO_ICON=/org/utplsql/sqldev/resources/images/info.png
+REFRESH_ICON=/org/utplsql/sqldev/resources/images/refresh.png
+RUN_ICON=/org/utplsql/sqldev/resources/images/run.png
+RUN_WORKSHEET_ICON=/org/utplsql/sqldev/resources/images/run_worksheet.png
+DEBUG_ICON=/org/utplsql/sqldev/resources/images/debug.png
+STOP_ICON=/org/utplsql/sqldev/resources/images/stop.png
+CLEAR_ICON=/org/utplsql/sqldev/resources/images/clear.png
+CHECKMARK_ICON=/org/utplsql/sqldev/resources/images/checkmark.png
+STATUS_ICON=/org/utplsql/sqldev/resources/images/status.png
+# progress.gif - the animated version - does not work
+PROGRESS_ICON=/org/utplsql/sqldev/resources/images/progress.png
+CODE_COVERAGE_ICON=/org/utplsql/sqldev/resources/images/coverage.png
+
+# Translatable text
+# suppress inspection "UnusedProperty"
+PREF_LABEL=utPLSQL
+PREF_USE_REALTIME_REPORTER_LABEL=Use realtime reporter?
+PREF_USE_REALTIME_REPORTER_HINT=Requires utPLSQL v3.1.4 or later. Opens a worksheet for older versions.
+PREF_UNSHARED_WORKSHEET_LABEL=Open an unshared worksheet?
+PREF_RESET_PACKAGE_LABEL=Reset package before running utPLSQL?
+PREF_CLEAR_SCREEN_LABEL=Clear script output panel before running utPLSQL?
+PREF_AUTO_EXECUTE_LABEL=Execute unit test automatically?
+PREF_CHECK_RUN_UTPLSQL_TEST_LABEL=Check availability of menu option?
+PREF_USE_SMART_TIMES_LABEL=Use smart times?
+PREF_IMPORT_SNIPPETS_BUTTON_LABEL=Import Snippets
+MENU_REALTIME_REPORTER_LABEL=Realtime Reporter
+PREF_NUMBER_OF_RUNS_IN_HISTORY_LABEL=Number of runs in history
+PREF_SHOW_DISABLED_COUNTER_LABEL=Show disabled counter?
+PREF_SHOW_WARNINGS_COUNTER_LABEL=Show warnings counter?
+PREF_SHOW_INFO_COUNTER_LABEL=Show info counter?
+PREF_SHOW_WARNING_INDICATOR_LABEL=Show warning indicator?
+PREF_SHOW_INFO_INDICATOR_LABEL=Show info indicator?
+PREF_SHOW_SUCCESSFUL_TESTS_LABEL=Show successful tests?
+PREF_SHOW_DISABLED_TESTS_LABEL=Show disabled tests?
+PREF_SHOW_TEST_DESCRIPTION_LABEL=Show description (if present)?
+PREF_SYNC_DETAIL_TAB_LABEL=Synchronize detail tab based on test status?
+PREF_TEST_PACKAGE_PREFIX_LABEL=Test package prefix
+PREF_TEST_PACKAGE_SUFFIX_LABEL=Test package suffix
+PREF_TEST_UNIT_PREFIX_LABEL=Test unit prefix
+PREF_TEST_UNIT_SUFFIX_LABEL=Test unit suffix
+PREF_NUMBER_OF_TESTS_PER_UNIT_LABEL=Number of tests to generate per unit
+PREF_GENERATE_COMMENTS_LABEL=Generate comments?
+PREF_DISABLE_TESTS_LABEL=Disable tests?
+PREF_SUITE_PATH_LABEL=Suite path
+PREF_INDENT_SPACES_LABEL=Indent spaces
+PREF_CHECK_GENERATE_UTPLSQL_TEST_LABEL=Check availability of menu option?
+PREF_CREATE_CODE_TEMPLATES_BUTTON_LABEL=Create code templates
+PREF_ROOT_FOLDER_IN_ODDGEN_VIEW_LABEL=Root folder in Generators view
+PREF_GENERATE_FILES_LABEL=Generate files?
+PREF_OUTPUT_DIRECTORY_LABEL=Output directory
+PREF_OUTPUT_DIRECTORY_BUTTON_LABEL=Browse
+PREF_DELETE_EXISTING_FILES_LABEL=Delete existing files in output directory?
+PREF_CONFIRM_IMPORT_TITLE=Snippets imported
+PREF_CONFIRM_IMPORT_MESSAGE=Snippets imported into %s. Please restart SQL Developer for this change to take effect.
+MENU_RUN_TEST_LABEL=Run utPLSQL test
+MENU_DEBUG_TEST_LABEL=Debug utPLSQL test...
+MENU_CODE_COVERAGE_LABEL=Code coverage...
+MENU_GENERATE_TEST_LABEL=Generate utPLSQL test
+WINDOW_CODE_COVERAGE_REPORT_LABEL=Code coverage report
+WINDOW_PATHS_LABEL=utPLSQL paths
+WINDOW_SCHEMAS_LABEL=Schemas under test
+WINDOW_INCLUDE_OBJECS_LABEL=Include objects
+WINDOW_EXCLUDE_OBJECS_LABEL=Exclude objects
+WINDOW_RUN_BUTTON=Run
+WINDOW_CANCEL_BUTTON=Cancel
+WORKSHEET_TITLE=utPLSQL
+RUNNER_VIEW_TITLE=utPLSQL
+RUNNER_REFRESH_TOOLTIP=Reset ordering and refresh
+RUNNER_RERUN_TOOLTIP=Rerun all tests
+RUNNER_RERUN_WORKSHEET_TOOLTIP=Rerun all tests in a new worksheet
+RUNNER_DEBUG_TOOLTIP=Rerun all tests with PL/SQL Debugger
+RUNNER_CODE_COVERAGE_TOOLTIP=Rerun all tests with code coverage
+RUNNER_STOP_TOOLTIP=Stops the consumer session of the current test run immediately, the JDBC connection might be closed delayed
+RUNNER_STOP_TEST_MESSAGE=Test disabled due to abortion of the test run.
+RUNNER_STOP_RUN_MESSAGE=Test run aborted.
+RUNNER_CLEAR_BUTTON=Clear run history
+RUNNER_TESTS_LABEL=Tests
+RUNNER_FAILURES_LABEL=Failures
+RUNNER_ERRORS_LABEL=Errors
+RUNNER_DISABLED_LABEL=Disabled
+RUNNER_WARNINGS_LABEL=Warnings
+RUNNER_INFO_LABEL=Info
+RUNNER_INITIALIZING_TEXT=Initializing...
+RUNNER_RUNNING_TEXT=Running tests...
+RUNNER_FINISHED_TEXT=Finished.
+RUNNER_NO_TESTS_FOUND_TEXT=No tests found.
+RUNNER_RUN_MENUITEM=Run test
+RUNNER_RUN_WORKSHEET_MENUITEM=Run test in new worksheet
+RUNNER_TEST_ID_COLUMN=Suitepath
+RUNNER_TEST_EXECUTION_TIME_COLUMN=Time
+RUNNER_OWNER_LABEL=Owner
+RUNNER_PACKAGE_LABEL=Package
+RUNNER_PROCEDURE_LABEL=Procedure
+RUNNER_DESCRIPTION_LABEL=Description
+RUNNER_START_LABEL=Start
+RUNNER_ASSERT_DESCRIPTION_COLUMN=Assert description (failed line)
+RUNNER_TEST_TAB_LABEL=Test
+RUNNER_FAILURES_TAB_LABEL=Failures
+RUNNER_ERRORS_TAB_LABEL=Errors
+RUNNER_WARNINGS_TAB_LABEL=Warnings
+RUNNER_INFO_TAB_LABEL=Info
diff --git a/sqldev/src/main/resources/org/utplsql/sqldev/resources/UtplsqlResources_de.properties b/sqldev/src/main/resources/org/utplsql/sqldev/resources/UtplsqlResources_de.properties
index 44bcbdcf..4da6a976 100644
--- a/sqldev/src/main/resources/org/utplsql/sqldev/resources/UtplsqlResources_de.properties
+++ b/sqldev/src/main/resources/org/utplsql/sqldev/resources/UtplsqlResources_de.properties
@@ -1,84 +1,91 @@
-# German resources for extension org.utplsql.sqldev
-
-# Translatable text
-PREF_LABEL=utPLSQL
-PREF_USE_REALTIME_REPORTER_LABEL=Realtime Reporter verwenden?
-PREF_USE_REALTIME_REPORTER_HINT=Benötigt utPLSQL v3.1.4 oder neuer. Öffnet ein Arbeitsblatt für ältere Versionen.
-PREF_UNSHARED_WORKSHEET_LABEL=Arbeitsblatt mit eigener Verbindung öffnen?
-PREF_RESET_PACKAGE_LABEL=Package vor der Ausführung von utPLSQL zurücksetzen?
-PREF_CLEAR_SCREEN_LABEL=Skriptausgabe-Fenster vor der Ausführung von utPLSQL leeren?
-PREF_AUTO_EXECUTE_LABEL=Unit Test automatisch ausführen?
-PREF_CHECK_RUN_UTPLSQL_TEST_LABEL=Verfügbarkeit der Menüoption prüfen?
-PREF_USE_SMART_TIMES_LABEL=Smarte Zeitangaben verwenden?
-PREF_IMPORT_SNIPPETS_BUTTON_LABEL=Code-Schnipsel importieren
-MENU_REALTIME_REPORTER_LABEL=Realtime Reporter
-PREF_NUMBER_OF_RUNS_IN_HISTORY_LABEL=Anzahl Ausführungen in der Historie
-PREF_SHOW_DISABLED_COUNTER_LABEL=Deaktiviert-Zähler anzeigen?
-PREF_SHOW_WARNINGS_COUNTER_LABEL=Warnungen-Zähler anzeigen?
-PREF_SHOW_INFO_COUNTER_LABEL=Info-Zähler anzeigen?
-PREF_SHOW_WARNING_INDICATOR_LABEL=Warnung-Indikator anzeigen?
-PREF_SHOW_INFO_INDICATOR_LABEL=Info-Indikator anzeigen?
-PREF_SHOW_SUCCESSFUL_TESTS_LABEL=Erfolgreiche Tests anzeigen?
-PREF_SHOW_DISABLED_TESTS_LABEL=Deaktivierte Tests anzeigen?
-PREF_SHOW_TEST_DESCRIPTION_LABEL=Beschreibung anzeigen (falls vorhanden)?
-PREF_SYNC_DETAIL_TAB_LABEL=Detailansicht basierend auf dem Teststatus synchronisieren?
-PREF_TEST_PACKAGE_PREFIX_LABEL=Test Package Präfix
-PREF_TEST_PACKAGE_SUFFIX_LABEL=Test Package Suffix
-PREF_TEST_UNIT_PREFIX_LABEL=Test Unit Präfix
-PREF_TEST_UNIT_SUFFIX_LABEL=Test Unit Suffix
-PREF_NUMBER_OF_TESTS_PER_UNIT_LABEL=Anzahl zu generierende Tests pro Unit
-PREF_GENERATE_COMMENTS_LABEL=Kommentare generieren?
-PREF_DISABLE_TESTS_LABEL=Tests deaktivieren?
-PREF_SUITE_PATH_LABEL=Suite-Pfad
-PREF_INDENT_SPACES_LABEL=Einrückungsleerzeichen
-PREF_CHECK_GENERATE_UTPLSQL_TEST_LABEL=Verfügbarkeit der Menüoption prüfen?
-PREF_CREATE_CODE_TEMPLATES_BUTTON_LABEL=Codevorlagen erstellen
-PREF_ROOT_FOLDER_IN_ODDGEN_VIEW_LABEL=Hauptverzeichnis in Generatoren Ansicht
-PREF_GENERATE_FILES_LABEL=Dateien generieren?
-PREF_OUTPUT_DIRECTORY_LABEL=Ausgabeverzeichnis
-PREF_OUTPUT_DIRECTORY_BUTTON_LABEL=Auswählen
-PREF_DELETE_EXISTING_FILES_LABEL=Bestehende Dateien im Ausgabeverzeichnis löschen?
-PREF_CONFIRM_IMPORT_TITLE=Code-Schnipsel importiert
-PREF_CONFIRM_IMPORT_MESSAGE=Code-Schnipsel in %s importiert. Bitte starten Sie den SQL Developer neu, um diese Änderung zu aktivieren.
-MENU_RUN_TEST_LABEL=utPLSQL Test ausführen
-MENU_CODE_COVERAGE_LABEL=Codeabdeckung...
-MENU_GENERATE_TEST_LABEL=utPLSQL Test generieren
-WINDOW_CODE_COVERAGE_REPORT_LABEL=Codeabdeckungs-Bericht
-WINDOW_PATHS_LABEL=utPLSQL Pfade
-WINDOW_SCHEMAS_LABEL=Schemata unter Test
-WINDOW_INCLUDE_OBJECS_LABEL=Inkludierte Objekte
-WINDOW_EXCLUDE_OBJECS_LABEL=Exkludierte Objekte
-WINDOW_RUN_BUTTON=Start
-WINDOW_CANCEL_BUTTON=Abbrechen
-WORKSHEET_TITLE=utPLSQL
-RUNNER_VIEW_TITLE=utPLSQL
-RUNNER_REFRESH_TOOLTIP=Sortierung zurücksetzen und aktualisieren
-RUNNER_RERUN_TOOLTIP=Alle Tests erneut ausführen
-RUNNER_RERUN_WORKSHEET_TOOLTIP=Alle Tests in einem neuen Arbeitsblatt erneut ausführen
-RUNNER_CODE_COVERAGE_TOOLTIP=Alle Tests mit Codeabdeckung ausführen
-RUNNER_CLEAR_BUTTON=Run History löschen
-RUNNER_TESTS_LABEL=Tests
-RUNNER_FAILURES_LABEL=Fehlschläge
-RUNNER_ERRORS_LABEL=Fehler
-RUNNER_DISABLED_LABEL=Deaktiviert
-RUNNER_WARNINGS_LABEL=Warnungen
-RUNNER_INFO_LABEL=Info
-RUNNER_INITIALIZING_TEXT=Initialisierung...
-RUNNER_RUNNING_TEXT=Starte Tests...
-RUNNER_FINNISHED_TEXT=Beendet.
-RUNNER_NO_TESTS_FOUND_TEXT=Keine Tests gefunden.
-RUNNER_RUN_MENUITEM=Run testTest ausführen
-RUNNER_RUN_WORKSHEET_MENUITEM=Test in neuem Arbeitsblatt ausführuen
-RUNNER_TEST_ID_COLUMN_NAME=Suitepath
-RUNNER_TEST_EXECUTION_TIME_COLUMN_NAME=Zeit
-RUNNER_OWNER_LABEL=Besitzer
-RUNNER_PACKAGE_LABEL=Paket
-RUNNER_PROCEDURE_LABEL=Prozedur
-RUNNER_DESCRIPTION_LABEL=Beschreibung
-RUNNER_START_LABEL=Start
-RUNNER_ASSERT_DESCRIPTION_COLUMN_NAME=Assert Beschreibung (gescheiterte Zeile)
-RUNNER_TEST_TAB_LABEL=Test
-RUNNER_FAILURES_TAB_LABEL=Misserfolge
-RUNNER_ERRORS_TAB_LABEL=Fehler
-RUNNER_WARNINGS_TAB_LABEL=Warnungen
-RUNNER_INFO_TAB_LABEL=Info
+# German resources for extension org.utplsql.sqldev
+# UTF-8 file works, as long as Umlaut are escaped, see https://www.utf8-chartable.de/
+
+# Translatable text
+# suppress inspection "UnusedProperty"
+PREF_LABEL=utPLSQL
+PREF_USE_REALTIME_REPORTER_LABEL=Realtime Reporter verwenden?
+PREF_USE_REALTIME_REPORTER_HINT=Ben\u00f6tigt utPLSQL v3.1.4 oder neuer. \u00d6ffnet ein Arbeitsblatt f\u00fcr \u00e4ltere Versionen.
+PREF_UNSHARED_WORKSHEET_LABEL=Arbeitsblatt mit eigener Verbindung \u00f6ffnen?
+PREF_RESET_PACKAGE_LABEL=Package vor der Ausf\u00fchrung von utPLSQL zur\u00fccksetzen?
+PREF_CLEAR_SCREEN_LABEL=Skriptausgabe-Fenster vor der Ausf\u00fchrung von utPLSQL leeren?
+PREF_AUTO_EXECUTE_LABEL=Unit Test automatisch ausf\u00fchren?
+PREF_CHECK_RUN_UTPLSQL_TEST_LABEL=Verf\u00fcgbarkeit der Men\u00fcoption pr\u00fcfen?
+PREF_USE_SMART_TIMES_LABEL=Smarte Zeitangaben verwenden?
+PREF_IMPORT_SNIPPETS_BUTTON_LABEL=Code-Schnipsel importieren
+MENU_REALTIME_REPORTER_LABEL=Realtime Reporter
+PREF_NUMBER_OF_RUNS_IN_HISTORY_LABEL=Anzahl Ausf\u00fchrungen in der Historie
+PREF_SHOW_DISABLED_COUNTER_LABEL=Deaktiviert-Z\u00e4hler anzeigen?
+PREF_SHOW_WARNINGS_COUNTER_LABEL=Warnungen-Z\u00e4hler anzeigen?
+PREF_SHOW_INFO_COUNTER_LABEL=Info-Z\u00e4hler anzeigen?
+PREF_SHOW_WARNING_INDICATOR_LABEL=Warnung-Indikator anzeigen?
+PREF_SHOW_INFO_INDICATOR_LABEL=Info-Indikator anzeigen?
+PREF_SHOW_SUCCESSFUL_TESTS_LABEL=Erfolgreiche Tests anzeigen?
+PREF_SHOW_DISABLED_TESTS_LABEL=Deaktivierte Tests anzeigen?
+PREF_SHOW_TEST_DESCRIPTION_LABEL=Beschreibung anzeigen (falls vorhanden)?
+PREF_SYNC_DETAIL_TAB_LABEL=Detailansicht basierend auf dem Teststatus synchronisieren?
+PREF_TEST_PACKAGE_PREFIX_LABEL=Test Package Pr\u00e4fix
+PREF_TEST_PACKAGE_SUFFIX_LABEL=Test Package Suffix
+PREF_TEST_UNIT_PREFIX_LABEL=Test Unit Pr\u00e4fix
+PREF_TEST_UNIT_SUFFIX_LABEL=Test Unit Suffix
+PREF_NUMBER_OF_TESTS_PER_UNIT_LABEL=Anzahl zu generierende Tests pro Unit
+PREF_GENERATE_COMMENTS_LABEL=Kommentare generieren?
+PREF_DISABLE_TESTS_LABEL=Tests deaktivieren?
+PREF_SUITE_PATH_LABEL=Suite-Pfad
+PREF_INDENT_SPACES_LABEL=Einr\u00fcckungsleerzeichen
+PREF_CHECK_GENERATE_UTPLSQL_TEST_LABEL=Verf\u00fcgbarkeit der Men\u00fcoption pr\u00fcfen?
+PREF_CREATE_CODE_TEMPLATES_BUTTON_LABEL=Codevorlagen erstellen
+PREF_ROOT_FOLDER_IN_ODDGEN_VIEW_LABEL=Hauptverzeichnis in Generatoren Ansicht
+PREF_GENERATE_FILES_LABEL=Dateien generieren?
+PREF_OUTPUT_DIRECTORY_LABEL=Ausgabeverzeichnis
+PREF_OUTPUT_DIRECTORY_BUTTON_LABEL=Ausw\u00e4hlen
+PREF_DELETE_EXISTING_FILES_LABEL=Bestehende Dateien im Ausgabeverzeichnis l\u00f6schen?
+PREF_CONFIRM_IMPORT_TITLE=Code-Schnipsel importiert
+PREF_CONFIRM_IMPORT_MESSAGE=Code-Schnipsel in %s importiert. Bitte starten Sie den SQL Developer neu, um diese \u00c4nderung zu aktivieren.
+MENU_RUN_TEST_LABEL=utPLSQL Test ausf\u00fchren
+MENU_DEBUG_TEST_LABEL=utPLSQL Test debuggen...
+MENU_CODE_COVERAGE_LABEL=Codeabdeckung...
+MENU_GENERATE_TEST_LABEL=utPLSQL Test generieren
+WINDOW_CODE_COVERAGE_REPORT_LABEL=Codeabdeckungs-Bericht
+WINDOW_PATHS_LABEL=utPLSQL Pfade
+WINDOW_SCHEMAS_LABEL=Schemata unter Test
+WINDOW_INCLUDE_OBJECS_LABEL=Inkludierte Objekte
+WINDOW_EXCLUDE_OBJECS_LABEL=Exkludierte Objekte
+WINDOW_RUN_BUTTON=Start
+WINDOW_CANCEL_BUTTON=Abbrechen
+WORKSHEET_TITLE=utPLSQL
+RUNNER_VIEW_TITLE=utPLSQL
+RUNNER_REFRESH_TOOLTIP=Sortierung zur\u00fccksetzen und aktualisieren
+RUNNER_RERUN_TOOLTIP=Alle Tests erneut ausf\u00fchren
+RUNNER_RERUN_WORKSHEET_TOOLTIP=Alle Tests in einem neuen Arbeitsblatt erneut ausf\u00fchren
+RUNNER_DEBUG_TOOLTIP=Alle Tests erneut mit dem PL/SQL Debugger ausf\u00fchren
+RUNNER_CODE_COVERAGE_TOOLTIP=Alle Tests mit Codeabdeckung ausf\u00fchren
+RUNNER_STOP_TOOLTIP=Stoppt die Verbrauchersitzung des aktuellen Testlaufs, die JDBC-Verbindung wird m\00f6glicherweise verz\00fgert geschlossen
+RUNNER_STOP_TEST_MESSAGE=Test wurde aufgrund eines Abbruchs des Testlaufs deaktiviert.
+RUNNER_STOP_RUN_MESSAGE=Testlauf abgebrochen.
+RUNNER_CLEAR_BUTTON=Run History l\u00f6schen
+RUNNER_TESTS_LABEL=Tests
+RUNNER_FAILURES_LABEL=Fehlschl\u00e4ge
+RUNNER_ERRORS_LABEL=Fehler
+RUNNER_DISABLED_LABEL=Deaktiviert
+RUNNER_WARNINGS_LABEL=Warnungen
+RUNNER_INFO_LABEL=Info
+RUNNER_INITIALIZING_TEXT=Initialisierung...
+RUNNER_RUNNING_TEXT=Starte Tests...
+RUNNER_FINISHED_TEXT=Beendet.
+RUNNER_NO_TESTS_FOUND_TEXT=Keine Tests gefunden.
+RUNNER_RUN_MENUITEM=Run testTest ausf\u00fchren
+RUNNER_RUN_WORKSHEET_MENUITEM=Test in neuem Arbeitsblatt ausf\u00fchren
+RUNNER_TEST_ID_COLUMN=Suitepath
+RUNNER_TEST_EXECUTION_TIME_COLUMN=Zeit
+RUNNER_OWNER_LABEL=Besitzer
+RUNNER_PACKAGE_LABEL=Paket
+RUNNER_PROCEDURE_LABEL=Prozedur
+RUNNER_DESCRIPTION_LABEL=Beschreibung
+RUNNER_START_LABEL=Start
+RUNNER_ASSERT_DESCRIPTION_COLUMN=Assert Beschreibung (gescheiterte Zeile)
+RUNNER_TEST_TAB_LABEL=Test
+RUNNER_FAILURES_TAB_LABEL=Misserfolge
+RUNNER_ERRORS_TAB_LABEL=Fehler
+RUNNER_WARNINGS_TAB_LABEL=Warnungen
+RUNNER_INFO_TAB_LABEL=Info
diff --git a/sqldev/src/main/resources/org/utplsql/sqldev/resources/images/debug.png b/sqldev/src/main/resources/org/utplsql/sqldev/resources/images/debug.png
new file mode 100644
index 00000000..1a27adf8
Binary files /dev/null and b/sqldev/src/main/resources/org/utplsql/sqldev/resources/images/debug.png differ
diff --git a/sqldev/src/main/resources/org/utplsql/sqldev/resources/images/stop.png b/sqldev/src/main/resources/org/utplsql/sqldev/resources/images/stop.png
new file mode 100755
index 00000000..015b8bd4
Binary files /dev/null and b/sqldev/src/main/resources/org/utplsql/sqldev/resources/images/stop.png differ
diff --git a/sqldev/src/test/java/org/utplsql/sqldev/test/JsonToStringStylerTest.java b/sqldev/src/test/java/org/utplsql/sqldev/test/JsonToStringStylerTest.java
index 2a0433cb..bbeb735d 100644
--- a/sqldev/src/test/java/org/utplsql/sqldev/test/JsonToStringStylerTest.java
+++ b/sqldev/src/test/java/org/utplsql/sqldev/test/JsonToStringStylerTest.java
@@ -15,13 +15,14 @@
*/
package org.utplsql.sqldev.test;
-import java.util.Arrays;
+import java.util.Collections;
import org.junit.Assert;
import org.junit.Test;
import org.utplsql.sqldev.model.runner.Run;
import org.utplsql.sqldev.model.ut.OutputLines;
+@SuppressWarnings("StringBufferReplaceableByString")
public class JsonToStringStylerTest {
@Test
@@ -64,7 +65,7 @@ public void outputLinesWithoutLines() {
@Test
public void emptyRun() {
- final Run r = new Run("1", "MyConnection", Arrays.asList());
+ final Run r = new Run("1", "MyConnection", Collections.emptyList());
final String actual = r.toString();
@@ -82,11 +83,11 @@ public void emptyRun() {
sb.append(" \"executionTime\": null,\n");
sb.append(" \"counter\": {\n");
sb.append(" \"className\": \"Counter\",\n");
- sb.append(" \"disabled\": null,\n");
- sb.append(" \"success\": null,\n");
- sb.append(" \"failure\": null,\n");
- sb.append(" \"error\": null,\n");
- sb.append(" \"warning\": null\n");
+ sb.append(" \"disabled\": 0,\n");
+ sb.append(" \"success\": 0,\n");
+ sb.append(" \"failure\": 0,\n");
+ sb.append(" \"error\": 0,\n");
+ sb.append(" \"warning\": 0\n");
sb.append(" },\n");
sb.append(" \"infoCount\": null,\n");
sb.append(" \"errorStack\": null,\n");
@@ -95,15 +96,14 @@ public void emptyRun() {
sb.append(" \"status\": null,\n");
sb.append(" \"start\": null,\n");
sb.append(" \"endTime\": null,\n");
- sb.append(" \"totalNumberOfCompletedTests\": -1\n");
+ sb.append(" \"totalNumberOfCompletedTests\": 0\n");
sb.append("}");
- Assert.assertEquals(sb.toString(), actual.toString());
+ Assert.assertEquals(sb.toString(), actual);
}
-
@Test
public void runWithTests() {
- final Run r = new Run("1", "MyConnection", Arrays.asList());
+ final Run r = new Run("1", "MyConnection", Collections.emptyList());
final org.utplsql.sqldev.model.runner.Test t1 = new org.utplsql.sqldev.model.runner.Test();
t1.setId("1");
t1.setName("Test One");
@@ -129,11 +129,11 @@ public void runWithTests() {
sb.append(" \"executionTime\": null,\n");
sb.append(" \"counter\": {\n");
sb.append(" \"className\": \"Counter\",\n");
- sb.append(" \"disabled\": null,\n");
- sb.append(" \"success\": null,\n");
- sb.append(" \"failure\": null,\n");
- sb.append(" \"error\": null,\n");
- sb.append(" \"warning\": null\n");
+ sb.append(" \"disabled\": 0,\n");
+ sb.append(" \"success\": 0,\n");
+ sb.append(" \"failure\": 0,\n");
+ sb.append(" \"error\": 0,\n");
+ sb.append(" \"warning\": 0\n");
sb.append(" },\n");
sb.append(" \"infoCount\": null,\n");
sb.append(" \"errorStack\": null,\n");
@@ -145,7 +145,14 @@ public void runWithTests() {
sb.append(" \"startTime\": null,\n");
sb.append(" \"endTime\": null,\n");
sb.append(" \"executionTime\": null,\n");
- sb.append(" \"counter\": null,\n");
+ sb.append(" \"counter\": {\n");
+ sb.append(" \"className\": \"Counter\",\n");
+ sb.append(" \"disabled\": 0,\n");
+ sb.append(" \"success\": 0,\n");
+ sb.append(" \"failure\": 0,\n");
+ sb.append(" \"error\": 0,\n");
+ sb.append(" \"warning\": 0\n");
+ sb.append(" },\n");
sb.append(" \"errorStack\": null,\n");
sb.append(" \"serverOutput\": null,\n");
sb.append(" \"warnings\": null,\n");
@@ -168,7 +175,14 @@ public void runWithTests() {
sb.append(" \"startTime\": null,\n");
sb.append(" \"endTime\": null,\n");
sb.append(" \"executionTime\": null,\n");
- sb.append(" \"counter\": null,\n");
+ sb.append(" \"counter\": {\n");
+ sb.append(" \"className\": \"Counter\",\n");
+ sb.append(" \"disabled\": 0,\n");
+ sb.append(" \"success\": 0,\n");
+ sb.append(" \"failure\": 0,\n");
+ sb.append(" \"error\": 0,\n");
+ sb.append(" \"warning\": 0\n");
+ sb.append(" },\n");
sb.append(" \"errorStack\": null,\n");
sb.append(" \"serverOutput\": null,\n");
sb.append(" \"warnings\": null,\n");
@@ -189,8 +203,8 @@ public void runWithTests() {
sb.append(" \"status\": null,\n");
sb.append(" \"start\": null,\n");
sb.append(" \"endTime\": null,\n");
- sb.append(" \"totalNumberOfCompletedTests\": -1\n");
+ sb.append(" \"totalNumberOfCompletedTests\": 0\n");
sb.append("}");
- Assert.assertEquals(sb.toString(), actual.toString());
+ Assert.assertEquals(sb.toString(), actual);
}
}
diff --git a/sqldev/src/test/java/org/utplsql/sqldev/test/SnippetTest.java b/sqldev/src/test/java/org/utplsql/sqldev/test/SnippetTest.java
index b3ebeb49..6922386f 100644
--- a/sqldev/src/test/java/org/utplsql/sqldev/test/SnippetTest.java
+++ b/sqldev/src/test/java/org/utplsql/sqldev/test/SnippetTest.java
@@ -30,11 +30,13 @@ public class SnippetTest {
@Test
public void mergeAsCopy() {
USER_SNIPPETS_FILE.delete();
+ Assert.assertFalse(USER_SNIPPETS_FILE.exists());
final SnippetMerger merger = new SnippetMerger(USER_SNIPPETS_FILE);
+ final String template = merger.getTemplate();
merger.merge();
Assert.assertTrue(USER_SNIPPETS_FILE.exists());
final String userSnippetsXml = new String(FileTools.readFile(USER_SNIPPETS_FILE.toPath()));
- Assert.assertEquals(merger.getTemplate(), userSnippetsXml);
+ Assert.assertEquals(template.length(), userSnippetsXml.length());
}
@Test
diff --git a/sqldev/src/test/java/org/utplsql/sqldev/test/runner/UtplsqlRunnerPanelTest.java b/sqldev/src/test/java/org/utplsql/sqldev/test/runner/UtplsqlRunnerPanelTest.java
index 59776833..b4da9385 100644
--- a/sqldev/src/test/java/org/utplsql/sqldev/test/runner/UtplsqlRunnerPanelTest.java
+++ b/sqldev/src/test/java/org/utplsql/sqldev/test/runner/UtplsqlRunnerPanelTest.java
@@ -18,7 +18,7 @@
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Toolkit;
-import java.util.Arrays;
+import java.util.Collections;
import java.util.UUID;
import javax.swing.JFrame;
@@ -38,7 +38,7 @@ public class UtplsqlRunnerPanelTest {
@Before
public void setup() {
final String reporterId = UUID.randomUUID().toString().replace("-", "");
- run = new Run(null, reporterId, Arrays.asList());
+ run = new Run(null, reporterId, Collections.emptyList());
run.setStartTime("2019-06-09T13:42:42.123456");
run.getCounter().setDisabled(0);
run.getCounter().setSuccess(0);
@@ -94,8 +94,8 @@ public void showGUI() {
run.getCounter().setSuccess(run.getCounter().getSuccess() + 1);
run.setStatus("utplsql.test.e");
final long end = System.currentTimeMillis();
- run.setExecutionTime(Double.valueOf(end - start) / 1000);
- run.setStatus(UtplsqlResources.getString("RUNNER_FINNISHED_TEXT"));
+ run.setExecutionTime((double) (end - start) / 1000);
+ run.setStatus(UtplsqlResources.getString("RUNNER_FINISHED_TEXT"));
panel.update(run.getReporterId());
SystemTools.sleep(2000);
Assert.assertNotNull(frame);