package de.is24.deadcode4j.analyzer;
import de.is24.deadcode4j.AnalysisContextBuilder;
import de.is24.deadcode4j.IntermediateResult;
import org.codehaus.plexus.util.ReflectionUtils;
import org.hamcrest.Matcher;
import org.hamcrest.collection.IsArrayContaining;
import org.junit.Test;
import org.mockito.internal.matchers.VarargMatcher;
import org.slf4j.Logger;
import java.util.Map;
import static com.google.common.collect.Maps.newHashMap;
import static com.google.common.collect.Sets.newHashSet;
import static de.is24.deadcode4j.AnalysisContextBuilder.givenAnalysisContext;
import static de.is24.deadcode4j.IntermediateResultMapBuilder.givenIntermediateResultMap;
import static org.hamcrest.Matchers.equalTo;
import static org.mockito.Matchers.argThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
public final class A_HibernateAnnotationsAnalyzer extends AByteCodeAnalyzer<HibernateAnnotationsAnalyzer> {
private static <T> Matcher<T[]> hasVarArgItem(Matcher<? super T> elementMatcher) {
return new MyVarArgsMatcher<T>(elementMatcher);
}
@Override
protected HibernateAnnotationsAnalyzer createAnalyzer() {
return new HibernateAnnotationsAnalyzer();
}
@Test
public void recognizesDependencyFromClassWithTypeAnnotatedFieldToTypeDefAnnotatedClass() {
analyzeFile("de/is24/deadcode4j/analyzer/hibernateannotations/ClassWithTypeDef.class");
analyzeFile("de/is24/deadcode4j/analyzer/hibernateannotations/ClassUsingTypeAtField.class");
assertThatDependenciesAreReportedFor("de.is24.deadcode4j.analyzer.hibernateannotations.ClassUsingTypeAtField",
"de.is24.deadcode4j.analyzer.hibernateannotations.ClassWithTypeDef");
}
@Test
public void recognizesDependencyFromClassWithTypeAnnotatedMethodToTypeDefAnnotatedClass() {
analyzeFile("de/is24/deadcode4j/analyzer/hibernateannotations/ClassWithTypeDef.class");
analyzeFile("de/is24/deadcode4j/analyzer/hibernateannotations/ClassUsingTypeAtMethod.class");
assertThatDependenciesAreReportedFor("de.is24.deadcode4j.analyzer.hibernateannotations.ClassUsingTypeAtMethod",
"de.is24.deadcode4j.analyzer.hibernateannotations.ClassWithTypeDef");
}
@Test
public void recognizesDependencyFromTypeAnnotatedClassesToTypeDefsAnnotatedPackage() {
analyzeFile("de/is24/deadcode4j/analyzer/hibernateannotations/Entity.class");
analyzeFile("de/is24/deadcode4j/analyzer/hibernateannotations/package-info.class");
analyzeFile("de/is24/deadcode4j/analyzer/hibernateannotations/AnotherEntity.class");
assertThatDependenciesAreReportedFor("de.is24.deadcode4j.analyzer.hibernateannotations.Entity",
"de.is24.deadcode4j.analyzer.hibernateannotations.package-info");
assertThatDependenciesAreReportedFor("de.is24.deadcode4j.analyzer.hibernateannotations.AnotherEntity",
"de.is24.deadcode4j.analyzer.hibernateannotations.package-info");
}
@Test
public void recognizesDependencyFromClassWithTypeAnnotatedMethodToReferencedClass() {
analyzeFile("de/is24/deadcode4j/analyzer/hibernateannotations/ClassUsingTypeWithoutTypeDef.class");
analyzeFile("IndependentClass.class");
assertThatDependenciesAreReportedFor("de.is24.deadcode4j.analyzer.hibernateannotations.ClassUsingTypeWithoutTypeDef",
"IndependentClass");
}
@Test
public void reportsDependencyToDefinedStrategyIfStrategyIsPartOfTheAnalysis() {
analyzeFile("de/is24/deadcode4j/analyzer/hibernateannotations/knownStrategies/ClassDefiningGenericGenerator.class");
assertThatDependenciesAreReportedFor("de.is24.deadcode4j.analyzer.hibernateannotations.knownStrategies.ClassDefiningGenericGenerator",
"IndependentClass");
}
@Test
public void doesNotReportDependencyToDefinedStrategyIfStrategyIsNoPartOfTheAnalysis() {
analyzeFile("de/is24/deadcode4j/analyzer/hibernateannotations/ClassDefiningGenericGenerator.class");
assertThatNoDependenciesAreReported();
}
@Test
public void reportsDependencyFromPackageToDefinedStrategies() {
analyzeFile("de/is24/deadcode4j/analyzer/hibernateannotations/knownStrategies/package-info.class");
assertThatDependenciesAreReportedFor("de.is24.deadcode4j.analyzer.hibernateannotations.knownStrategies.package-info",
"IndependentClass", "DependingClass");
}
@Test
public void recognizesDependencyFromClassWithGeneratedValueAnnotatedFieldToGenericGeneratorAnnotatedClass() {
analyzeFile("de/is24/deadcode4j/analyzer/hibernateannotations/ClassDefiningGenericGenerator.class");
analyzeFile("de/is24/deadcode4j/analyzer/hibernateannotations/ClassUsingGeneratedValueAtField.class");
assertThatDependenciesAreReportedFor("de.is24.deadcode4j.analyzer.hibernateannotations.ClassUsingGeneratedValueAtField",
"de.is24.deadcode4j.analyzer.hibernateannotations.ClassDefiningGenericGenerator");
}
@Test
public void recognizesDependencyFromClassWithGeneratedValueAnnotatedMethodToGenericGeneratorAnnotatedPackage() {
analyzeFile("de/is24/deadcode4j/analyzer/hibernateannotations/ClassDefiningGenericGenerator.class");
analyzeFile("de/is24/deadcode4j/analyzer/hibernateannotations/ClassUsingGeneratedValueAtMethod.class");
assertThatDependenciesAreReportedFor("de.is24.deadcode4j.analyzer.hibernateannotations.ClassUsingGeneratedValueAtMethod",
"de.is24.deadcode4j.analyzer.hibernateannotations.ClassDefiningGenericGenerator");
}
@Test
public void recognizesDependencyFromGeneratedValueAnnotatedClassesToGenericGeneratorAnnotatedPackage() {
analyzeFile("de/is24/deadcode4j/analyzer/hibernateannotations/AnotherEntityWithGeneratedValue.class");
analyzeFile("de/is24/deadcode4j/analyzer/hibernateannotations/EntityWithGeneratedValue.class");
analyzeFile("de/is24/deadcode4j/analyzer/hibernateannotations/package-info.class");
assertThatDependenciesAreReportedFor("de.is24.deadcode4j.analyzer.hibernateannotations.AnotherEntityWithGeneratedValue",
"de.is24.deadcode4j.analyzer.hibernateannotations.package-info");
assertThatDependenciesAreReportedFor("de.is24.deadcode4j.analyzer.hibernateannotations.EntityWithGeneratedValue",
"de.is24.deadcode4j.analyzer.hibernateannotations.package-info");
}
@Test
public void storesTypeDefinitionsAsIntermediateResults() {
analyzeFile("de/is24/deadcode4j/analyzer/hibernateannotations/package-info.class");
assertThatIntermediateResultIsStored();
}
@Test
public void storesTypeUsagesAsIntermediateResults() {
analyzeFile("de/is24/deadcode4j/analyzer/hibernateannotations/Entity.class");
assertThatIntermediateResultIsStored();
}
@Test
public void considersTypeDefinitionsFromIntermediateResults() {
this.analysisContext = givenAnalysisContext(
this.analysisContext.getModule(),
HibernateAnnotationsAnalyzer.class.getName() + "|typeDefinitions",
givenIntermediateResultMap("byteClass", "Foo"));
analyzeFile("de/is24/deadcode4j/analyzer/hibernateannotations/Entity.class");
assertThatDependenciesAreReportedFor("de.is24.deadcode4j.analyzer.hibernateannotations.Entity", "Foo");
}
@Test
public void prefersOwnTypeDefinitionsOverIntermediateResults() {
this.analysisContext = givenAnalysisContext(
this.analysisContext.getModule(),
HibernateAnnotationsAnalyzer.class.getName() + "|typeDefinitions",
givenIntermediateResultMap("byteClass", "Foo"));
analyzeFile("de/is24/deadcode4j/analyzer/hibernateannotations/Entity.class");
analyzeFile("de/is24/deadcode4j/analyzer/hibernateannotations/package-info.class");
assertThatDependenciesAreReportedFor("de.is24.deadcode4j.analyzer.hibernateannotations.Entity",
"de.is24.deadcode4j.analyzer.hibernateannotations.package-info");
}
@Test
public void considersTypeUsagesFromIntermediateResults() {
this.analysisContext = givenAnalysisContext(
this.analysisContext.getModule(),
HibernateAnnotationsAnalyzer.class.getName() + "|typeUsages",
givenIntermediateResultMap("byteClass", newHashSet("Foo", "Bar")));
analyzeFile("de/is24/deadcode4j/analyzer/hibernateannotations/package-info.class");
assertThatDependenciesAreReportedFor("Foo", "de.is24.deadcode4j.analyzer.hibernateannotations.package-info");
assertThatDependenciesAreReportedFor("Bar", "de.is24.deadcode4j.analyzer.hibernateannotations.package-info");
}
@Test
public void ignoresTypeUsagesFromIntermediateResultsForTypeDefinitionsFromIntermediateResults() {
Map<Object, IntermediateResult> intermediateResults = newHashMap();
intermediateResults.put(HibernateAnnotationsAnalyzer.class.getName() + "|typeUsages",
givenIntermediateResultMap("byteClass", newHashSet("Bar")));
intermediateResults.put(HibernateAnnotationsAnalyzer.class.getName() + "|typeDefinitions",
givenIntermediateResultMap("byteClass", "Foo"));
this.analysisContext = AnalysisContextBuilder.givenAnalysisContext(this.analysisContext.getModule(), intermediateResults);
analyzeFile("de/is24/deadcode4j/analyzer/hibernateannotations/EntityWithGeneratedValue.class");
assertThatNoDependenciesAreReported();
}
@Test
public void storesGeneratorDefinitionsAsIntermediateResults() {
analyzeFile("de/is24/deadcode4j/analyzer/hibernateannotations/package-info.class");
assertThatIntermediateResultIsStored();
}
@Test
public void storesGeneratorUsagesAsIntermediateResults() {
analyzeFile("de/is24/deadcode4j/analyzer/hibernateannotations/EntityWithGeneratedValue.class");
assertThatIntermediateResultIsStored();
}
@Test
public void considersGeneratorDefinitionsFromIntermediateResults() {
this.analysisContext = givenAnalysisContext(
this.analysisContext.getModule(),
HibernateAnnotationsAnalyzer.class.getName() + "|generatorDefinitions",
givenIntermediateResultMap("generatorOne", "Foo"));
analyzeFile("de/is24/deadcode4j/analyzer/hibernateannotations/EntityWithGeneratedValue.class");
assertThatDependenciesAreReportedFor(
"de.is24.deadcode4j.analyzer.hibernateannotations.EntityWithGeneratedValue", "Foo");
}
@Test
public void prefersOwnGeneratorDefinitionsOverIntermediateResults() {
this.analysisContext = givenAnalysisContext(
this.analysisContext.getModule(),
HibernateAnnotationsAnalyzer.class.getName() + "|generatorDefinitions",
givenIntermediateResultMap("generatorOne", "Foo"));
analyzeFile("de/is24/deadcode4j/analyzer/hibernateannotations/EntityWithGeneratedValue.class");
analyzeFile("de/is24/deadcode4j/analyzer/hibernateannotations/package-info.class");
assertThatDependenciesAreReportedFor("de.is24.deadcode4j.analyzer.hibernateannotations.EntityWithGeneratedValue",
"de.is24.deadcode4j.analyzer.hibernateannotations.package-info");
}
@Test
public void considersGeneratorUsagesFromIntermediateResults() {
this.analysisContext = givenAnalysisContext(
this.analysisContext.getModule(),
HibernateAnnotationsAnalyzer.class.getName() + "|generatorUsages",
givenIntermediateResultMap("generatorOne", newHashSet("Foo", "Bar")));
analyzeFile("de/is24/deadcode4j/analyzer/hibernateannotations/package-info.class");
assertThatDependenciesAreReportedFor("Foo", "de.is24.deadcode4j.analyzer.hibernateannotations.package-info");
assertThatDependenciesAreReportedFor("Bar", "de.is24.deadcode4j.analyzer.hibernateannotations.package-info");
}
@Test
public void ignoresGeneratorUsagesFromIntermediateResultsForGeneratorDefinitionsFromIntermediateResults() {
Map<Object, IntermediateResult> intermediateResults = newHashMap();
intermediateResults.put(HibernateAnnotationsAnalyzer.class.getName() + "|generatorUsages",
givenIntermediateResultMap("generatorOne", newHashSet("Bar")));
intermediateResults.put(HibernateAnnotationsAnalyzer.class.getName() + "|generatorDefinitions",
givenIntermediateResultMap("generatorOne", "Foo"));
this.analysisContext = AnalysisContextBuilder.givenAnalysisContext(this.analysisContext.getModule(), intermediateResults);
analyzeFile("de/is24/deadcode4j/analyzer/hibernateannotations/Entity.class");
assertThatNoDependenciesAreReported();
}
@Test
public void issuesWarningForDuplicatedTypeDef() throws IllegalAccessException {
Logger loggerMock = mock(Logger.class);
ReflectionUtils.setVariableValueInObject(objectUnderTest, "logger", loggerMock);
analyzeFile("de/is24/deadcode4j/analyzer/hibernateannotations/ClassWithTypeDef.class");
analyzeFile("de/is24/deadcode4j/analyzer/hibernateannotations/ClassWithDuplicatedTypeDef.class");
finishAnalysis();
verify(loggerMock).warn(
org.mockito.Matchers.contains("@TypeDef"),
(Object[]) argThat(hasVarArgItem(equalTo("aRandomType"))));
}
private static class MyVarArgsMatcher<T> extends IsArrayContaining<T> implements VarargMatcher {
public MyVarArgsMatcher(Matcher<? super T> elementMatcher) {
super(elementMatcher);
}
}
}