blob: f83c98224717c8aeca6b3703f4d8c6adca6b534b [file] [log] [blame]
/**
* Copyright 2006-2013 the original author or authors.
*
* 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.objenesis.tck;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.SortedSet;
import java.util.TreeSet;
/**
* Reports results from TCK as tabulated text, suitable for dumping to the console or a file and
* being read by a human. If can be reused to provide a summary reports of different candidates as
* long as the same objenesisDescription is not used twice.
*
* @author Joe Walnes
* @author Henri Tremblay
* @see TCK
* @see Reporter
*/
public class TextReporter implements Reporter {
private static class Result {
String objenesisDescription;
String candidateDescription;
boolean result;
Exception exception;
/**
* @param objenesisDescription Description of the tested Objenesis instance
* @param candidateDescription Description of the tested candidate
* @param result If the test is successful or not
* @param exception Exception that might have occured during the test
*/
public Result(String objenesisDescription, String candidateDescription, boolean result,
Exception exception) {
this.objenesisDescription = objenesisDescription;
this.candidateDescription = candidateDescription;
this.result = result;
this.exception = exception;
}
}
private final PrintStream summary;
private final PrintStream log;
private long startTime;
private long totalTime = 0;
private int errorCount = 0;
private SortedSet allCandidates = new TreeSet();
private SortedSet allInstantiators = new TreeSet();
private String currentObjenesis;
private String currentCandidate;
private Map objenesisResults = new HashMap();
private String platformDescription;
/**
* @param summary Output of main report.
* @param log Any additional information, useful for diagnostics.
*/
public TextReporter(PrintStream summary, PrintStream log) {
this.summary = summary;
this.log = log;
}
public void startTests(String platformDescription, Collection allCandidates,
Collection allInstantiators) {
// HT: in case the same reporter is reused, I'm guessing that it will
// always be the
// same platform
this.platformDescription = platformDescription;
this.allCandidates.addAll(allCandidates);
this.allInstantiators.addAll(allInstantiators);
for(Iterator it = allInstantiators.iterator(); it.hasNext();) {
objenesisResults.put(it.next(), new HashMap());
}
startTime = System.currentTimeMillis();
}
public void startTest(String candidateDescription, String objenesisDescription) {
currentCandidate = candidateDescription;
currentObjenesis = objenesisDescription;
}
public void result(boolean instantiatedObject) {
if(!instantiatedObject) {
errorCount++;
}
((Map) objenesisResults.get(currentObjenesis)).put(currentCandidate, new Result(
currentObjenesis, currentCandidate, instantiatedObject, null));
}
public void exception(Exception exception) {
errorCount++;
((Map) objenesisResults.get(currentObjenesis)).put(currentCandidate, new Result(
currentObjenesis, currentCandidate, false, exception));
}
public void endTest() {
}
public void endTests() {
totalTime += System.currentTimeMillis() - startTime;
}
/**
* Print the final summary report
*/
public void printResult(boolean parentConstructorTest) {
// Platform
summary.println("Running TCK on platform: " + platformDescription);
summary.println();
summary.println("Not serializable parent constructor called: "
+ (parentConstructorTest ? 'Y' : 'N'));
summary.println();
if(!parentConstructorTest) {
errorCount++;
}
int maxObjenesisWidth = lengthOfLongestStringIn(allInstantiators);
int maxCandidateWidth = lengthOfLongestStringIn(allCandidates);
// Header
summary.print(pad("", maxCandidateWidth) + ' ');
for(Iterator it = allInstantiators.iterator(); it.hasNext();) {
String desc = (String) it.next();
summary.print(pad(desc, maxObjenesisWidth) + ' ');
}
summary.println();
List exceptions = new ArrayList();
// Candidates (and keep the exceptions meanwhile)
for(Iterator it = allCandidates.iterator(); it.hasNext();) {
String candidateDesc = (String) it.next();
summary.print(pad(candidateDesc, maxCandidateWidth) + ' ');
for(Iterator itInst = allInstantiators.iterator(); itInst.hasNext();) {
String instDesc = (String) itInst.next();
Result result = (Result) ((Map) objenesisResults.get(instDesc)).get(candidateDesc);
if(result == null) {
summary.print(pad("N/A", maxObjenesisWidth) + " ");
}
else {
summary.print(pad(result.result ? "Y" : "n", maxObjenesisWidth) + " ");
if(result.exception != null) {
exceptions.add(result);
}
}
}
summary.println();
}
summary.println();
// Final
if(errorCount != 0) {
for(Iterator it = exceptions.iterator(); it.hasNext();) {
Result element = (Result) it.next();
log.println("--- Candidate '" + element.candidateDescription + "', Instantiator '"
+ element.objenesisDescription + "' ---");
element.exception.printStackTrace(log);
log.println();
}
log.println();
summary.println("--- FAILED: " + errorCount + " error(s) occured ---");
}
else {
summary.println("--- SUCCESSFUL: TCK tests passed without errors in " + totalTime + " ms");
}
summary.println();
}
private String pad(String text, int width) {
if(text.length() == width) {
return text;
}
else if(text.length() > width) {
return text.substring(0, width);
}
else {
StringBuffer padded = new StringBuffer(text);
while(padded.length() < width) {
padded.append(' ');
}
return padded.toString();
}
}
private int lengthOfLongestStringIn(Collection descriptions) {
int result = 0;
for(Iterator it = descriptions.iterator(); it.hasNext();) {
result = Math.max(result, ((String) it.next()).length());
}
return result;
}
}