diff options
author | Ashlee Young <ashlee@onosfw.com> | 2015-09-09 22:15:21 -0700 |
---|---|---|
committer | Ashlee Young <ashlee@onosfw.com> | 2015-09-09 22:15:21 -0700 |
commit | 13d05bc8458758ee39cb829098241e89616717ee (patch) | |
tree | 22a4d1ce65f15952f07a3df5af4b462b4697cb3a /framework/src/onos/utils/junit/src/main/java/org/onlab/junit/UtilityClassChecker.java | |
parent | 6139282e1e93c2322076de4b91b1c85d0bc4a8b3 (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.java | 149 |
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); + } + } +} |