package org.mutabilitydetector.cli;
/*
* #%L
* MutabilityDetector
* %%
* Copyright (C) 2008 - 2014 Graham Allan
* %%
* 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.
* #L%
*/
import static java.util.Collections.singleton;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.containsString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.mutabilitydetector.AnalysisResult.analysisResult;
import static org.mutabilitydetector.MutabilityReason.CAN_BE_SUBCLASSED;
import static org.mutabilitydetector.MutabilityReason.MUTABLE_TYPE_TO_FIELD;
import static org.mutabilitydetector.MutableReasonDetail.newMutableReasonDetail;
import static org.mutabilitydetector.TestUtil.unusedMutableReasonDetails;
import static org.mutabilitydetector.locations.CodeLocation.ClassLocation.from;
import static org.mutabilitydetector.locations.CodeLocation.ClassLocation.fromInternalName;
import static org.mutabilitydetector.locations.Slashed.slashed;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import org.junit.Test;
import org.mutabilitydetector.AnalysisResult;
import org.mutabilitydetector.AnalysisSession;
import org.mutabilitydetector.IsImmutable;
import org.mutabilitydetector.MutableReasonDetail;
import org.mutabilitydetector.cli.CommandLineOptions.ReportMode;
import org.mutabilitydetector.locations.CodeLocation.FieldLocation;
import org.mutabilitydetector.misc.TimingUtil;
public class SessionResultsFormatterTest {
private final ClassListReaderFactory unusedReaderFactory = null;
private final String newline = System.getProperty("line.separator");
@Test
public void printsReadableMessage() throws Exception {
BatchAnalysisOptions options = mock(BatchAnalysisOptions.class);
when(options.reportMode()).thenReturn(ReportMode.ALL);
when(options.isUsingClassList()).thenReturn(false);
AnalysisSession analysisSession = mock(AnalysisSession.class);
Collection<AnalysisResult> analysisResults = Arrays.asList(analysisResult("a.b.c",
IsImmutable.IMMUTABLE,
unusedMutableReasonDetails()),
analysisResult("d.e.f",
IsImmutable.EFFECTIVELY_IMMUTABLE,
unusedMutableReasonDetails()),
analysisResult("g.h.i",
IsImmutable.NOT_IMMUTABLE,
unusedMutableReasonDetails()));
when(analysisSession.getResults()).thenReturn(analysisResults);
SessionResultsFormatter formatter = new SessionResultsFormatter(options, unusedReaderFactory);
StringBuilder result = formatter.format(analysisSession.getResults(), analysisSession.getErrors());
assertThat(result.toString(),
allOf(containsString("a.b.c is IMMUTABLE" + newline),
containsString("d.e.f is EFFECTIVELY_IMMUTABLE" + newline),
containsString("g.h.i is NOT_IMMUTABLE" + newline)));
}
@Test
public void verboseOutputIncludesDetailedReasonAndPrettyPrintedCodeLocation() throws Exception {
Collection<MutableReasonDetail> reasons = Arrays.asList(newMutableReasonDetail("1st checker reason message",
from(slashed("path/to/MyClass")),
CAN_BE_SUBCLASSED),
newMutableReasonDetail("2nd checker reason message",
FieldLocation.fieldLocation("myField",
fromInternalName("path/to/OtherClass")),
MUTABLE_TYPE_TO_FIELD));
BatchAnalysisOptions options = mock(BatchAnalysisOptions.class);
when(options.reportMode()).thenReturn(ReportMode.ALL);
when(options.isUsingClassList()).thenReturn(false);
when(options.verbose()).thenReturn(true);
AnalysisSession analysisSession = mock(AnalysisSession.class);
Collection<AnalysisResult> analysisResults = singleton(analysisResult("a.b.c", IsImmutable.NOT_IMMUTABLE, reasons));
when(analysisSession.getResults()).thenReturn(analysisResults);
SessionResultsFormatter formatter = new SessionResultsFormatter(options, unusedReaderFactory);
StringBuilder result = formatter.format(analysisSession.getResults(), analysisSession.getErrors());
assertThat(result.toString(),
containsString("a.b.c is NOT_IMMUTABLE" + newline +
"\t1st checker reason message [Class: path.to.MyClass]" + newline +
"\t2nd checker reason message [Field: myField, Class: path.to.OtherClass]" + newline));
}
@Test
public void printsSummaryOfInformationAlongWithReadableMessage() throws Exception {
BatchAnalysisOptions options = mock(BatchAnalysisOptions.class);
when(options.reportMode()).thenReturn(ReportMode.ALL);
when(options.isUsingClassList()).thenReturn(false);
when(options.showSummary()).thenReturn(true);
TimingUtil timingUtil = mock(TimingUtil.class);
when(timingUtil.getCurrentTimeMillis()).thenReturn(23000l);
when(timingUtil.getVMStartTimeMillis()).thenReturn(16000l);
AnalysisSession analysisSession = mock(AnalysisSession.class);
Collection<AnalysisResult> analysisResults = Arrays.asList(analysisResult("a.b.c",
IsImmutable.IMMUTABLE,
unusedMutableReasonDetails()),
analysisResult("d.e.f",
IsImmutable.EFFECTIVELY_IMMUTABLE,
unusedMutableReasonDetails()),
analysisResult("g.h.i",
IsImmutable.NOT_IMMUTABLE,
unusedMutableReasonDetails()));
when(analysisSession.getResults()).thenReturn(analysisResults);
SessionResultsFormatter formatter = new SessionResultsFormatter(options, unusedReaderFactory);
formatter.setTimingUtil(timingUtil);
StringBuilder result = formatter.format(analysisSession.getResults(), analysisSession.getErrors());
assertThat(result.toString(),
allOf(containsString("a.b.c is IMMUTABLE" + newline),
containsString("d.e.f is EFFECTIVELY_IMMUTABLE" + newline),
containsString("g.h.i is NOT_IMMUTABLE" + newline),
containsString("3 Total number of classes scanned." + newline),
containsString("2 IMMUTABLE class(es)." + newline),
containsString("1 NOT_IMMUTABLE class(es)." + newline),
containsString("7 seconds runtime." + newline)
));
}
}