From 9205b621a07f5dd13218c66a5f926ebd6e59f754 Mon Sep 17 00:00:00 2001
From: Robert Scott <code@humanleg.org.uk>
Date: Sat, 9 Jun 2018 12:55:33 +0100
Subject: [PATCH v2 27/28] ExtendedDialogMocker, HelpAwareOptionPaneMocker,
 JOptionPaneSimpleMocker: add invocations raising AssertionError to invocation
 log

---
 .../testutils/mockers/ExtendedDialogMocker.java    |  32 ++--
 .../mockers/HelpAwareOptionPaneMocker.java         | 104 +++++------
 .../testutils/mockers/JOptionPaneSimpleMocker.java | 190 ++++++++++++---------
 3 files changed, 183 insertions(+), 143 deletions(-)

diff --git a/test/unit/org/openstreetmap/josm/testutils/mockers/ExtendedDialogMocker.java b/test/unit/org/openstreetmap/josm/testutils/mockers/ExtendedDialogMocker.java
index f0fb62f29..4401f64fa 100644
--- a/test/unit/org/openstreetmap/josm/testutils/mockers/ExtendedDialogMocker.java
+++ b/test/unit/org/openstreetmap/josm/testutils/mockers/ExtendedDialogMocker.java
@@ -39,7 +39,7 @@ import mockit.Mock;
  * only the parts necessary for a particular case.
  *
  * The default {@link #getMockResult(ExtendedDialog)} will raise an
- * {@link junit.framework.AssertionFailedError} on an {@link ExtendedDialog} activation without a
+ * {@link AssertionError} on an {@link ExtendedDialog} activation without a
  * matching mapping entry or if the named button doesn't exist.
  *
  * The public {@link #getMockResultMap()} method returns the modifiable result map to allow for situations
@@ -127,17 +127,25 @@ public class ExtendedDialogMocker extends BaseDialogMockUp<ExtendedDialog> {
     @Mock
     private void setVisible(final Invocation invocation, final boolean value) {
         if (value == true) {
-            final ExtendedDialog instance = invocation.getInvokedInstance();
-            final int mockResult = this.getMockResult(instance);
-            // TODO check validity of mockResult?
-            Deencapsulation.setField(instance, "result", mockResult);
-            Logging.info(
-                "{0} answering {1} to ExtendedDialog with content {2}",
-                this.getClass().getName(),
-                mockResult,
-                this.getString(instance)
-            );
-            this.getInvocationLogInternal().add(this.getInvocationLogEntry(instance, mockResult));
+            try {
+                final ExtendedDialog instance = invocation.getInvokedInstance();
+                final int mockResult = this.getMockResult(instance);
+                // TODO check validity of mockResult?
+                Deencapsulation.setField(instance, "result", mockResult);
+                Logging.info(
+                    "{0} answering {1} to ExtendedDialog with content {2}",
+                    this.getClass().getName(),
+                    mockResult,
+                    this.getString(instance)
+                );
+                this.getInvocationLogInternal().add(this.getInvocationLogEntry(instance, mockResult));
+            } catch (AssertionError e) {
+                // in case this exception gets ignored by the calling thread we want to signify this failure
+                // in the invocation log. it's hard to know what to add to the log in these cases as it's
+                // probably unsafe to call getInvocationLogEntry, so add the exception on its own.
+                this.getInvocationLogInternal().add(new Object[] {e});
+                throw e;
+            }
         }
     }
 
diff --git a/test/unit/org/openstreetmap/josm/testutils/mockers/HelpAwareOptionPaneMocker.java b/test/unit/org/openstreetmap/josm/testutils/mockers/HelpAwareOptionPaneMocker.java
index a157df4e7..54fd3eba7 100644
--- a/test/unit/org/openstreetmap/josm/testutils/mockers/HelpAwareOptionPaneMocker.java
+++ b/test/unit/org/openstreetmap/josm/testutils/mockers/HelpAwareOptionPaneMocker.java
@@ -40,7 +40,7 @@ import mockit.Mock;
  * of only the parts necessary for a particular case.
  *
  * The default {@link #getMockResultForMessage(Object)} will raise an
- * {@link junit.framework.AssertionFailedError} on an {@link #showOptionDialog(Component, Object, String,
+ * {@link AssertionError} on an {@link #showOptionDialog(Component, Object, String,
  * int, Icon, HelpAwareOptionPane.ButtonSpec[], HelpAwareOptionPane.ButtonSpec, String)}
  * activation without a matching mapping entry or if the named button doesn't exist.
  *
@@ -134,59 +134,67 @@ public class HelpAwareOptionPaneMocker extends BaseDialogMockUp<HelpAwareOptionP
         final HelpAwareOptionPane.ButtonSpec defaultOption,
         final String helpTopic
     ) {
-        final Object result = this.getMockResultForMessage(msg);
+        try {
+            final Object result = this.getMockResultForMessage(msg);
+
+            if (result == null) {
+                fail(
+                    "Invalid result for HelpAwareOptionPane: null (HelpAwareOptionPane returns"
+                    + "JOptionPane.OK_OPTION for closed windows if that was the intent)"
+                );
+            }
 
-        if (result == null) {
-            fail(
-                "Invalid result for HelpAwareOptionPane: null (HelpAwareOptionPane returns"
-                + "JOptionPane.OK_OPTION for closed windows if that was the intent)"
-            );
-        }
+            Integer retval = null;
+            if (result instanceof String) {
+                retval = this.getButtonPositionFromLabel(options, (String) result);
+            } else if (result instanceof Integer) {
+                retval = (Integer) result;
+            } else {
+                throw new IllegalArgumentException(
+                    "HelpAwareOptionPane message mapped to unsupported type of Object: " + result
+                );
+            }
 
-        Integer retval = null;
-        if (result instanceof String) {
-            retval = this.getButtonPositionFromLabel(options, (String) result);
-        } else if (result instanceof Integer) {
-            retval = (Integer) result;
-        } else {
-            throw new IllegalArgumentException(
-                "HelpAwareOptionPane message mapped to unsupported type of Object: " + result
+            // check the returned integer for validity
+            if (retval < 0) {
+                fail(String.format(
+                    "Invalid result for HelpAwareOptionPane: %s (HelpAwareOptionPane returns "
+                    + "JOptionPane.OK_OPTION for closed windows if that was the intent)",
+                    retval
+                ));
+            } else if (retval > (options == null ? 0 : options.length)) {  // NOTE 1-based indexing
+                fail(String.format(
+                    "Invalid result for HelpAwareOptionPane: %s (in call with options = %s)",
+                    retval,
+                    options
+                ));
+            }
+
+            Logging.info(
+                "{0} answering {1} to HelpAwareOptionPane with message {2}",
+                this.getClass().getName(),
+                retval,
+                this.getStringFromMessage(msg)
             );
-        }
 
-        // check the returned integer for validity
-        if (retval < 0) {
-            fail(String.format(
-                "Invalid result for HelpAwareOptionPane: %s (HelpAwareOptionPane returns "
-                + "JOptionPane.OK_OPTION for closed windows if that was the intent)",
+            this.getInvocationLogInternal().add(this.getInvocationLogEntry(
+                msg,
+                title,
+                messageType,
+                icon,
+                options,
+                defaultOption,
+                helpTopic,
                 retval
             ));
-        } else if (retval > (options == null ? 0 : options.length)) {  // NOTE 1-based indexing
-            fail(String.format(
-                "Invalid result for HelpAwareOptionPane: %s (in call with options = %s)",
-                retval,
-                options
-            ));
-        }
 
-        Logging.info(
-            "{0} answering {1} to HelpAwareOptionPane with message {2}",
-            this.getClass().getName(),
-            retval,
-            this.getStringFromMessage(msg)
-        );
-
-        this.getInvocationLogInternal().add(this.getInvocationLogEntry(
-            msg,
-            title,
-            messageType,
-            icon,
-            options,
-            defaultOption,
-            helpTopic,
-            retval
-        ));
-
-        return retval;
+            return retval;
+        } catch (AssertionError e) {
+            // in case this exception gets ignored by the calling thread we want to signify this failure
+            // in the invocation log. it's hard to know what to add to the log in these cases as it's
+            // probably unsafe to call getInvocationLogEntry, so add the exception on its own.
+            this.getInvocationLogInternal().add(new Object[] {e});
+            throw e;
+        }
     }
 }
diff --git a/test/unit/org/openstreetmap/josm/testutils/mockers/JOptionPaneSimpleMocker.java b/test/unit/org/openstreetmap/josm/testutils/mockers/JOptionPaneSimpleMocker.java
index 256ee8ba0..8dae51174 100644
--- a/test/unit/org/openstreetmap/josm/testutils/mockers/JOptionPaneSimpleMocker.java
+++ b/test/unit/org/openstreetmap/josm/testutils/mockers/JOptionPaneSimpleMocker.java
@@ -46,7 +46,7 @@ import mockit.MockUp;
  * only the parts necessary for a particular case.
  *
  * The default {@link #getMockResultForMessage(Object)} will raise an
- * {@link junit.framework.AssertionFailedError} on an activation without a matching mapping entry or if
+ * {@link junit.framework.AssertionError} on an activation without a matching mapping entry or if
  * the mapped result value is invalid for the call.
  *
  * The public {@link #getMockResultMap()} method returns the modifiable result map to allow for situations
@@ -161,42 +161,50 @@ public class JOptionPaneSimpleMocker extends BaseDialogMockUp<JOptionPane> {
         final Object[] selectionValues,
         final Object initialSelectionValue
     ) {
-        final Object result = this.getMockResultForMessage(message);
-        if (selectionValues == null) {
-            if (!(result instanceof String)) {
-                fail(String.format(
-                    "Only valid result type for showInputDialog with null selectionValues is String: received %s",
-                    result
-                ));
+        try {
+            final Object result = this.getMockResultForMessage(message);
+            if (selectionValues == null) {
+                if (!(result instanceof String)) {
+                    fail(String.format(
+                        "Only valid result type for showInputDialog with null selectionValues is String: received %s",
+                        result
+                    ));
+                }
+            } else {
+                if (!Arrays.asList(selectionValues).contains(result)) {
+                    fail(String.format(
+                        "Result for showInputDialog not present in selectionValues: %s",
+                        result
+                    ));
+                }
             }
-        } else {
-            if (!Arrays.asList(selectionValues).contains(result)) {
-                fail(String.format(
-                    "Result for showInputDialog not present in selectionValues: %s",
-                    result
-                ));
-            }
-        }
 
-        Logging.info(
-            "{0} answering {1} to showInputDialog with message {2}",
-            this.getClass().getName(),
-            result,
-            this.getStringFromMessage(message)
-        );
+            Logging.info(
+                "{0} answering {1} to showInputDialog with message {2}",
+                this.getClass().getName(),
+                result,
+                this.getStringFromMessage(message)
+            );
 
-        this.getInvocationLogInternal().add(this.getInvocationLogEntry(
-            message,
-            title,
-            null,
-            messageType,
-            icon,
-            selectionValues,
-            initialSelectionValue,
-            result
-        ));
+            this.getInvocationLogInternal().add(this.getInvocationLogEntry(
+                message,
+                title,
+                null,
+                messageType,
+                icon,
+                selectionValues,
+                initialSelectionValue,
+                result
+            ));
 
-        return result;
+            return result;
+        } catch (AssertionError e) {
+            // in case this exception gets ignored by the calling thread we want to signify this failure
+            // in the invocation log. it's hard to know what to add to the log in these cases as it's
+            // probably unsafe to call getInvocationLogEntry, so add the exception on its own.
+            this.getInvocationLogInternal().add(new Object[] {e});
+            throw e;
+        }
     }
 
     @Mock
@@ -207,34 +215,42 @@ public class JOptionPaneSimpleMocker extends BaseDialogMockUp<JOptionPane> {
         final int messageType,
         final Icon icon
     ) {
-        // why look up a "result" for a message dialog which can only have one possible result? it's
-        // a good opportunity to assert its contents
-        final Object result = this.getMockResultForMessage(message);
-        if (!(result instanceof Integer && (int) result == JOptionPane.OK_OPTION)) {
-            fail(String.format(
-                "Only valid result for showMessageDialog is %d: received %s",
-                JOptionPane.OK_OPTION,
-                result
-            ));
-        }
+        try {
+            // why look up a "result" for a message dialog which can only have one possible result? it's
+            // a good opportunity to assert its contents
+            final Object result = this.getMockResultForMessage(message);
+            if (!(result instanceof Integer && (int) result == JOptionPane.OK_OPTION)) {
+                fail(String.format(
+                    "Only valid result for showMessageDialog is %d: received %s",
+                    JOptionPane.OK_OPTION,
+                    result
+                ));
+            }
 
-        Logging.info(
-            "{0} answering {1} to showMessageDialog with message {2}",
-            this.getClass().getName(),
-            result,
-            this.getStringFromMessage(message)
-        );
+            Logging.info(
+                "{0} answering {1} to showMessageDialog with message {2}",
+                this.getClass().getName(),
+                result,
+                this.getStringFromMessage(message)
+            );
 
-        this.getInvocationLogInternal().add(this.getInvocationLogEntry(
-            message,
-            title,
-            null,
-            messageType,
-            icon,
-            null,
-            null,
-            JOptionPane.OK_OPTION
-        ));
+            this.getInvocationLogInternal().add(this.getInvocationLogEntry(
+                message,
+                title,
+                null,
+                messageType,
+                icon,
+                null,
+                null,
+                JOptionPane.OK_OPTION
+            ));
+        } catch (AssertionError e) {
+            // in case this exception gets ignored by the calling thread we want to signify this failure
+            // in the invocation log. it's hard to know what to add to the log in these cases as it's
+            // probably unsafe to call getInvocationLogEntry, so add the exception on its own.
+            this.getInvocationLogInternal().add(new Object[] {e});
+            throw e;
+        }
     }
 
     @Mock
@@ -246,34 +262,42 @@ public class JOptionPaneSimpleMocker extends BaseDialogMockUp<JOptionPane> {
         final int messageType,
         final Icon icon
     ) {
-        final Object result = this.getMockResultForMessage(message);
-        if (!(result instanceof Integer && Ints.contains(optionTypePermittedResults.get(optionType), (int) result))) {
-            fail(String.format(
-                "Invalid result for showConfirmDialog with optionType %d: %s",
+        try {
+            final Object result = this.getMockResultForMessage(message);
+            if (!(result instanceof Integer && Ints.contains(optionTypePermittedResults.get(optionType), (int) result))) {
+                fail(String.format(
+                    "Invalid result for showConfirmDialog with optionType %d: %s",
+                    optionType,
+                    result
+                ));
+            }
+
+            Logging.info(
+                "{0} answering {1} to showConfirmDialog with message {2}",
+                this.getClass().getName(),
+                result,
+                this.getStringFromMessage(message)
+            );
+
+            this.getInvocationLogInternal().add(this.getInvocationLogEntry(
+                message,
+                title,
                 optionType,
+                messageType,
+                icon,
+                null,
+                null,
                 result
             ));
-        }
-
-        Logging.info(
-            "{0} answering {1} to showConfirmDialog with message {2}",
-            this.getClass().getName(),
-            result,
-            this.getStringFromMessage(message)
-        );
 
-        this.getInvocationLogInternal().add(this.getInvocationLogEntry(
-            message,
-            title,
-            optionType,
-            messageType,
-            icon,
-            null,
-            null,
-            result
-        ));
-
-        return (int) result;
+            return (int) result;
+        } catch (AssertionError e) {
+            // in case this exception gets ignored by the calling thread we want to signify this failure
+            // in the invocation log. it's hard to know what to add to the log in these cases as it's
+            // probably unsafe to call getInvocationLogEntry, so add the exception on its own.
+            this.getInvocationLogInternal().add(new Object[] {e});
+            throw e;
+        }
     }
 
     /**
-- 
2.11.0

