/* * Copyright 2011 Henry Coles * * 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.pitest.junit; import java.lang.annotation.Inherited; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.List; import org.junit.experimental.categories.Category; import org.pitest.classinfo.ClassInfo; import org.pitest.classinfo.ClassName; import org.pitest.testapi.TestClassIdentifier; import org.pitest.testapi.TestGroupConfig; public class JUnitTestClassIdentifier implements TestClassIdentifier { private final TestGroupConfig config; private final Collection<String> excludedRunners; public JUnitTestClassIdentifier(final TestGroupConfig config, final Collection<String> excludedRunners) { this.config = config; this.excludedRunners = excludedRunners; } @Override public boolean isATestClass(final ClassInfo a) { return TestInfo.isWithinATestClass(a); } @Override public boolean isIncluded(final ClassInfo a) { return isIncludedCategory(a) && !isExcludedCategory(a) && isNotRanWithExcludedRunner(a); } private boolean isNotRanWithExcludedRunner(final ClassInfo a) { final String runWith = getRunWithAnnotationValue(a); return !this.excludedRunners.contains(runWith); } private String getRunWithAnnotationValue(final ClassInfo a) { Object classAnnotationValue = a.getClassAnnotationValue(new ClassName("org.junit.runner.RunWith")); if (classAnnotationValue == null && a.getSuperClass().hasSome()) { classAnnotationValue = getRunWithAnnotationValue(a.getSuperClass().value()); } return (String) classAnnotationValue; } private boolean isIncludedCategory(final ClassInfo a) { final List<String> included = this.config.getIncludedGroups(); return included.isEmpty() || !Collections.disjoint(included, Arrays.asList(getCategories(a))); } private boolean isExcludedCategory(final ClassInfo a) { final List<String> excluded = this.config.getExcludedGroups(); return !excluded.isEmpty() && !Collections.disjoint(excluded, Arrays.asList(getCategories(a))); } private String[] getCategories(final ClassInfo a) { final Class<Category> categoryClass = Category.class; final Object[] categoryArray = (Object[]) a.getClassAnnotationValue(ClassName.fromClass(categoryClass)); if (categoryArray == null) { final boolean isCategoryInherited = categoryClass.isAnnotationPresent(Inherited.class); if (isCategoryInherited && a.getSuperClass().hasSome()) { return getCategories(a.getSuperClass().value()); } else { return new String[]{}; } } return copyArray(categoryArray); } private String[] copyArray(final Object[] original) { final String[] copy = new String[original.length]; System.arraycopy(original, 0, copy, 0, original.length); return copy; } }