package de.is24.deadcode4j; import de.is24.deadcode4j.junit.LoggingRule; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import javax.annotation.Nonnull; import java.util.Map; import static de.is24.deadcode4j.ModuleBuilder.givenModule; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.*; public final class An_IntermediateResults { @Rule public final LoggingRule enableLogging = new LoggingRule(); private IntermediateResults objectUnderTest; @Before public void setUp() throws Exception { objectUnderTest = new IntermediateResults(); } @Test public void transfersIntermediateResultsForDependingModule() { Object key = getClass(); AnalysisContext parentContext = AnalysisContextBuilder.givenAnalysisContext(givenModule("A")); parentContext.getCache().put(key, new AnIntermediateResult("ForA")); objectUnderTest.add(parentContext); Map<Object, IntermediateResult> intermediateResults = objectUnderTest.calculateIntermediateResultsFor(givenModule("B", parentContext.getModule())); assertThat(intermediateResults, hasEntry(is(key), hasToString("ForA"))); } @Test public void transfersIntermediateResultsForDependingModuleOfDependingModule() { Object key = getClass(); AnalysisContext parentContext = AnalysisContextBuilder.givenAnalysisContext(givenModule("A")); parentContext.getCache().put(key, new AnIntermediateResult("ForA")); objectUnderTest.add(parentContext); Map<Object, IntermediateResult> intermediateResults = objectUnderTest.calculateIntermediateResultsFor( givenModule("C", givenModule("B", parentContext.getModule()))); assertThat(intermediateResults, hasEntry(is(key), hasToString("ForA"))); } @Test public void mergesIntermediateResultsOnSiblingLevel() { Object key = getClass(); AnalysisContext parentContext = AnalysisContextBuilder.givenAnalysisContext(givenModule("A")); parentContext.getCache().put(key, new AnIntermediateResult("ForA")); AnalysisContext secondParentContext = AnalysisContextBuilder.givenAnalysisContext(givenModule("B")); secondParentContext.getCache().put(key, new AnIntermediateResult("ForB")); objectUnderTest.add(parentContext); objectUnderTest.add(secondParentContext); Map<Object, IntermediateResult> intermediateResults = objectUnderTest.calculateIntermediateResultsFor( givenModule("C", parentContext.getModule(), secondParentContext.getModule())); assertThat(intermediateResults, hasEntry(is(key), hasToString("ForA+ForB"))); } @Test public void mergesIntermediateResultsOnParentLevel() { Object key = getClass(); AnalysisContext rootContext = AnalysisContextBuilder.givenAnalysisContext(givenModule("A")); rootContext.getCache().put(key, new AnIntermediateResult("ForA")); AnalysisContext parentContext = AnalysisContextBuilder.givenAnalysisContext(givenModule("B", rootContext.getModule())); parentContext.getCache().put(key, new AnIntermediateResult("ForB")); objectUnderTest.add(rootContext); objectUnderTest.add(parentContext); Map<Object, IntermediateResult> intermediateResults = objectUnderTest.calculateIntermediateResultsFor( givenModule("C", parentContext.getModule())); assertThat(intermediateResults, hasEntry(is(key), hasToString("ForB->(ForA)"))); } @Test public void nowAllTogether() { Object key = getClass(); AnalysisContext rootContext = AnalysisContextBuilder.givenAnalysisContext(givenModule("A")); rootContext.getCache().put(key, new AnIntermediateResult("ForA")); AnalysisContext secondRootContext = AnalysisContextBuilder.givenAnalysisContext(givenModule("Z")); secondRootContext.getCache().put(key, new AnIntermediateResult("ForZ")); AnalysisContext parentContext = AnalysisContextBuilder.givenAnalysisContext(givenModule("B", rootContext.getModule())); parentContext.getCache().put(key, new AnIntermediateResult("ForB")); AnalysisContext secondParentContext = AnalysisContextBuilder.givenAnalysisContext(givenModule("C", rootContext.getModule(), secondRootContext.getModule())); secondParentContext.getCache().put(key, new AnIntermediateResult("ForC")); AnalysisContext thirdParentContext = AnalysisContextBuilder.givenAnalysisContext(givenModule("D")); thirdParentContext.getCache().put(key, new AnIntermediateResult("ForD")); AnalysisContext fourthParentContext = AnalysisContextBuilder.givenAnalysisContext(givenModule("Y", secondRootContext.getModule())); fourthParentContext.getCache().put(key, new AnIntermediateResult("ForY")); AnalysisContext childContext = AnalysisContextBuilder.givenAnalysisContext(givenModule("X", fourthParentContext.getModule())); childContext.getCache().put(key, new AnIntermediateResult("ForX")); objectUnderTest.add(rootContext); objectUnderTest.add(secondRootContext); objectUnderTest.add(parentContext); objectUnderTest.add(secondParentContext); objectUnderTest.add(thirdParentContext); objectUnderTest.add(fourthParentContext); objectUnderTest.add(childContext); Map<Object, IntermediateResult> intermediateResults = objectUnderTest.calculateIntermediateResultsFor( givenModule("E", parentContext.getModule(), secondParentContext.getModule(), thirdParentContext.getModule(), childContext.getModule()) ); assertThat(intermediateResults, hasEntry(is(key), hasToString("ForB->(ForA)+ForC->(ForA+ForZ)+ForD+ForX->(ForY->(ForZ))"))); } private static class AnIntermediateResult implements IntermediateResult { private final String string; public AnIntermediateResult(String string) { this.string = string; } @Override public boolean equals(Object obj) { return this == obj || AnIntermediateResult.class.isInstance(obj) && this.string.equals(AnIntermediateResult.class.cast(obj).string); } @Override public int hashCode() { return this.string.hashCode(); } @Override public String toString() { return this.string; } @Nonnull @Override public IntermediateResult mergeSibling(@Nonnull IntermediateResult sibling) { return new AnIntermediateResult(this.string + "+" + sibling); } @Nonnull @Override public IntermediateResult mergeParent(@Nonnull IntermediateResult parent) { return new AnIntermediateResult(this.string + "->(" + parent + ")"); } } }