/*
* Copyright (C) 2010 The Android Open Source Project
*
* 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 vogar;
import com.google.common.collect.Lists;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import vogar.util.Strings;
/**
* An outcome of an action. Some actions may have multiple outcomes. For
* example, JUnit tests have one outcome for each test method.
*/
public final class Outcome {
private final String outcomeName;
private final Result result;
private final String output;
private final Date date;
public Outcome(String outcomeName, Result result, List<String> outputLines) {
this.outcomeName = outcomeName;
this.result = result;
this.output = sanitizeOutputLines(outputLines);
this.date = new Date();
}
public Outcome(String outcomeName, Result result, String outputLine, Date date) {
this.outcomeName = outcomeName;
this.result = result;
this.output = sanitizeOutputLine(outputLine);
this.date = date;
}
public Outcome(String outcomeName, Result result, String outputLine) {
this.outcomeName = outcomeName;
this.result = result;
this.output = sanitizeOutputLine(outputLine);
this.date = new Date();
}
public Outcome(String outcomeName, Result result, Throwable throwable) {
this.outcomeName = outcomeName;
this.result = result;
this.output = sanitizeOutputLines(throwableToLines(throwable));
this.date = new Date();
}
private String sanitizeOutputLines(List<String> outputLines) {
List<String> sanitizedStrings = Lists.newArrayList();
for (String line : outputLines) {
sanitizedStrings.add(sanitizeOutputLine(line));
}
return Strings.join(sanitizedStrings, "\n");
}
private String sanitizeOutputLine(String outputLine) {
return Strings.xmlSanitize(outputLine.replaceAll("\r\n?", "\n"));
}
public Date getDate() {
return date;
}
public String getName() {
return outcomeName;
}
public Result getResult() {
return result;
}
public String getOutput() {
return output;
}
public List<String> getOutputLines() {
return Arrays.asList(output.split("\n"));
}
private static List<String> throwableToLines(Throwable t) {
StringWriter writer = new StringWriter();
PrintWriter out = new PrintWriter(writer);
t.printStackTrace(out);
return Arrays.asList(writer.toString().split("\\n"));
}
/**
* Returns the action's suite name, such as java.lang.Integer or
* java.lang.IntegerTest.
*/
public String getSuiteName() {
int split = split(outcomeName);
return split == -1 ? "defaultpackage" : outcomeName.substring(0, split);
}
/**
* Returns the specific action name, such as BitTwiddle or testBitTwiddle.
*/
public String getTestName() {
int split = split(outcomeName);
return split == -1 ? outcomeName : outcomeName.substring(split + 1);
}
private static int split(String name) {
int lastHash = name.indexOf('#');
return lastHash == -1 ? name.lastIndexOf('.') : lastHash;
}
/**
* Returns whether the result indicates that the contents of the Outcome are important.
*
* For example, for a test skipped because it is unsupported, we don't care about the result.
*/
private boolean matters() {
return result != Result.UNSUPPORTED;
}
public ResultValue getResultValue(Expectation expectation) {
if (matters()) {
return expectation.matches(this) ? ResultValue.OK : ResultValue.FAIL;
}
return ResultValue.IGNORE;
}
/**
* Returns a filesystem db path for this outcome. For example, a path for an outcome with name
* "foo.bar.baz#testName" would be "foo/bar/baz/testName".
*/
public String getPath() {
return outcomeName.replaceAll("[\\.#]", "/");
}
@Override public boolean equals(Object o) {
if (o instanceof Outcome) {
Outcome outcome = (Outcome) o;
return outcomeName.equals(outcome.outcomeName)
&& result == outcome.result
&& output.equals(outcome.output);
}
return false;
}
@Override public int hashCode() {
int hashCode = 17;
hashCode = 37 * hashCode + outcomeName.hashCode();
hashCode = 37 * hashCode + result.hashCode();
hashCode = 37 * hashCode + output.hashCode();
return hashCode;
}
@Override public String toString() {
return "Outcome[name=" + outcomeName + " output=" + output + "]";
}
}