summaryrefslogtreecommitdiffstats
path: root/framework/src/onos/utils/junit/src/main/java/org/onlab/junit/UtilityClassChecker.java
diff options
context:
space:
mode:
authorAshlee Young <ashlee@onosfw.com>2015-09-09 22:15:21 -0700
committerAshlee Young <ashlee@onosfw.com>2015-09-09 22:15:21 -0700
commit13d05bc8458758ee39cb829098241e89616717ee (patch)
tree22a4d1ce65f15952f07a3df5af4b462b4697cb3a /framework/src/onos/utils/junit/src/main/java/org/onlab/junit/UtilityClassChecker.java
parent6139282e1e93c2322076de4b91b1c85d0bc4a8b3 (diff)
ONOS checkin based on commit tag e796610b1f721d02f9b0e213cf6f7790c10ecd60
Change-Id: Ife8810491034fe7becdba75dda20de4267bd15cd
Diffstat (limited to 'framework/src/onos/utils/junit/src/main/java/org/onlab/junit/UtilityClassChecker.java')
-rw-r--r--framework/src/onos/utils/junit/src/main/java/org/onlab/junit/UtilityClassChecker.java149
1 files changed, 149 insertions, 0 deletions
diff --git a/framework/src/onos/utils/junit/src/main/java/org/onlab/junit/UtilityClassChecker.java b/framework/src/onos/utils/junit/src/main/java/org/onlab/junit/UtilityClassChecker.java
new file mode 100644
index 00000000..9c623cee
--- /dev/null
+++ b/framework/src/onos/utils/junit/src/main/java/org/onlab/junit/UtilityClassChecker.java
@@ -0,0 +1,149 @@
+/*
+ * Copyright 2014 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onlab.junit;
+
+import org.hamcrest.Description;
+import org.hamcrest.StringDescription;
+import org.onlab.junit.TestUtils.TestUtilsException;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+
+
+/**
+ * Hamcrest style class for verifying that a class follows the
+ * accepted rules for utility classes.
+ *
+ * The rules that are enforced for utility classes:
+ * - the class must be declared final
+ * - the class must have only one constructor
+ * - the constructor must be private and inaccessible to callers
+ * - the class must have only static methods
+ */
+
+public class UtilityClassChecker {
+
+ private String failureReason = "";
+
+ /**
+ * Method to determine if a given class is a properly specified
+ * utility class. In addition to checking that the class meets the criteria
+ * for utility classes, an object of the class type is allocated to force
+ * test code coverage onto the class constructor.
+ *
+ * @param clazz the class to check
+ * @return true if the given class is a properly specified utility class.
+ */
+ private boolean isProperlyDefinedUtilityClass(Class<?> clazz) {
+ // class must be declared final
+ if (!Modifier.isFinal(clazz.getModifiers())) {
+ failureReason = "a class that is not final";
+ return false;
+ }
+
+ // class must have only one constructor
+ final Constructor<?>[] constructors = clazz.getDeclaredConstructors();
+ if (constructors.length != 1) {
+ failureReason = "a class with more than one constructor";
+ return false;
+ }
+
+ // constructor must not be accessible outside of the class
+ final Constructor<?> constructor = constructors[0];
+ if (constructor.isAccessible()) {
+ failureReason = "a class with an accessible default constructor";
+ return false;
+ }
+
+ // constructor must be private
+ if (!Modifier.isPrivate(constructor.getModifiers())) {
+ failureReason = "a class with a default constructor that is not private";
+ return false;
+ }
+
+ // class must have only static methods
+ for (final Method method : clazz.getMethods()) {
+ if (method.getDeclaringClass().equals(clazz)) {
+ if (!Modifier.isStatic(method.getModifiers())) {
+ failureReason = "a class with one or more non-static methods";
+ return false;
+ }
+ }
+
+ }
+
+ try {
+ final Object newObject = TestUtils.callConstructor(constructor);
+ if (newObject == null) {
+ failureReason = "could not instantiate a new object";
+ return false;
+ }
+ } catch (TestUtilsException e) {
+ failureReason = "could not instantiate a new object";
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Describe why an error was reported. Uses Hamcrest style Description
+ * interfaces.
+ *
+ * @param description the Description object to use for reporting the
+ * mismatch
+ */
+ public void describeMismatch(Description description) {
+ description.appendText(failureReason);
+ }
+
+ /**
+ * Describe the source object that caused an error, using a Hamcrest
+ * Matcher style interface. In this case, it always returns
+ * that we are looking for a properly defined utility class.
+ *
+ * @param description the Description object to use to report the "to"
+ * object
+ */
+ public void describeTo(Description description) {
+ description.appendText("a properly defined utility class");
+ }
+
+ /**
+ * Assert that the given class adheres to the utility class rules.
+ *
+ * @param clazz the class to check
+ *
+ * @throws java.lang.AssertionError if the class is not a valid
+ * utility class
+ */
+ public static void assertThatClassIsUtility(Class<?> clazz) {
+ final UtilityClassChecker checker = new UtilityClassChecker();
+ if (!checker.isProperlyDefinedUtilityClass(clazz)) {
+ final Description toDescription = new StringDescription();
+ final Description mismatchDescription = new StringDescription();
+
+ checker.describeTo(toDescription);
+ checker.describeMismatch(mismatchDescription);
+ final String reason =
+ "\n" +
+ "Expected: is \"" + toDescription.toString() + "\"\n" +
+ " but : was \"" + mismatchDescription.toString() + "\"";
+
+ throw new AssertionError(reason);
+ }
+ }
+}