You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by ah...@apache.org on 2022/11/30 13:35:17 UTC
[commons-statistics] 01/15: Add test to assert internal method getMedian is not public/protected
This is an automated email from the ASF dual-hosted git repository.
aherbert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-statistics.git
commit 6266e0f67e0391fbe9be6444958e9d192d26a312
Author: aherbert <ah...@apache.org>
AuthorDate: Wed Nov 30 11:11:53 2022 +0000
Add test to assert internal method getMedian is not public/protected
---
.../BaseContinuousDistributionTest.java | 4 +++
.../distribution/BaseDiscreteDistributionTest.java | 4 +++
.../distribution/BaseDistributionTest.java | 34 ++++++++++++++++++++++
3 files changed, 42 insertions(+)
diff --git a/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/BaseContinuousDistributionTest.java b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/BaseContinuousDistributionTest.java
index 5d27d5e..1a40b0f 100644
--- a/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/BaseContinuousDistributionTest.java
+++ b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/BaseContinuousDistributionTest.java
@@ -16,6 +16,7 @@
*/
package org.apache.commons.statistics.distribution;
+import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -960,6 +961,8 @@ abstract class BaseContinuousDistributionTest
* The median is used internally for computation of the probability of a range
* using either the CDF or survival function. If overridden by a distribution it should
* be equivalent to the inverse CDF called with 0.5.
+ *
+ * <p>The method modifiers are asserted to check the method is not public or protected.
*/
@ParameterizedTest
@MethodSource
@@ -967,6 +970,7 @@ abstract class BaseContinuousDistributionTest
if (dist instanceof AbstractContinuousDistribution) {
final AbstractContinuousDistribution d = (AbstractContinuousDistribution) dist;
TestUtils.assertEquals(d.inverseCumulativeProbability(0.5), d.getMedian(), tolerance, "median");
+ assertMethodNotModified(dist.getClass(), Modifier.PUBLIC | Modifier.PROTECTED, "getMedian");
}
}
}
diff --git a/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/BaseDiscreteDistributionTest.java b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/BaseDiscreteDistributionTest.java
index 7dad929..a36b9ef 100644
--- a/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/BaseDiscreteDistributionTest.java
+++ b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/BaseDiscreteDistributionTest.java
@@ -16,6 +16,7 @@
*/
package org.apache.commons.statistics.distribution;
+import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -1154,6 +1155,8 @@ abstract class BaseDiscreteDistributionTest
* The median is used internally for computation of the probability of a range
* using either the CDF or survival function. If overridden by a distribution it should
* be equivalent to the inverse CDF called with 0.5.
+ *
+ * <p>The method modifiers are asserted to check the method is not public or protected.
*/
@ParameterizedTest
@MethodSource
@@ -1161,6 +1164,7 @@ abstract class BaseDiscreteDistributionTest
if (dist instanceof AbstractDiscreteDistribution) {
final AbstractDiscreteDistribution d = (AbstractDiscreteDistribution) dist;
Assertions.assertEquals(d.inverseCumulativeProbability(0.5), d.getMedian(), "median");
+ assertMethodNotModified(dist.getClass(), Modifier.PUBLIC | Modifier.PROTECTED, "getMedian");
}
}
}
diff --git a/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/BaseDistributionTest.java b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/BaseDistributionTest.java
index 2371014..9e25620 100644
--- a/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/BaseDistributionTest.java
+++ b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/BaseDistributionTest.java
@@ -20,6 +20,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -611,6 +612,39 @@ abstract class BaseDistributionTest<T, D extends DistributionTestData> {
return data.stream().map(d -> Arguments.of(d.getParameters()));
}
+ /**
+ * Assert the named method on the class is not modified with the specified modifiers.
+ *
+ * <p>This uses reflection to traverse the object hierarchy to search for the named
+ * method. It can be used to assert that internal methods are not exposed in the API
+ * as public or protected.
+ *
+ * @param cls Class.
+ * @param modifiers Disallowed modifiers.
+ * @param name Name of the method.
+ * @param parameterTypes Array of parameter types for the method.
+ * @see Method#getModifiers()
+ * @see Class#getDeclaredMethod(String, Class...)
+ * @see java.lang.reflect.Modifier
+ */
+ static void assertMethodNotModified(Class<?> cls, int modifiers, String name, Class<?>... parameterTypes) {
+ // getMethod will only find public methods.
+ // using getDeclaredMethod can access private methods but it
+ // only applies to the current class so we traverse the hierarchy.
+ for (Class<?> c = cls; c != null; c = c.getSuperclass()) {
+ try {
+ final Method method = cls.getDeclaredMethod(name, parameterTypes);
+ final int flags = method.getModifiers() & modifiers;
+ Assertions.assertEquals(0, flags,
+ () -> "Method " + name + " has disallowed modifiers: " + Modifier.toString(flags));
+ } catch (NoSuchMethodException ignore) {
+ // The class does not declare the method
+ } catch (SecurityException e) {
+ Assertions.fail("Cannot search for " + name + " using reflection", e);
+ }
+ }
+ }
+
//------------------------ Tests -----------------------------
// Tests are final. It is expected that the test can be modified by overriding