|
Groovy example source code file (AssertionRenderer.java)
This example Groovy source code file (AssertionRenderer.java) is included in the DevDaily.com
"Java Source Code
Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.
The Groovy AssertionRenderer.java source code
/*
* Copyright 2008 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.codehaus.groovy.runtime.powerassert;
import java.util.*;
import org.codehaus.groovy.runtime.DefaultGroovyMethods;
/**
* Creates a string representation of an assertion and its recorded values.
*
* @author Peter Niederwieser
*/
public final class AssertionRenderer {
private final String text;
private final ValueRecorder recorder;
private final List<StringBuilder> lines = new ArrayList();
// startColumns.get(i) is the first non-empty column of lines.get(i)
private final List<Integer> startColumns = new ArrayList();
private AssertionRenderer(String text, ValueRecorder recorder) {
if (text.contains("\n"))
throw new IllegalArgumentException("source text may not contain line breaks");
this.text = text;
this.recorder = recorder;
}
/**
* Creates a string representation of an assertion and its recorded values.
*
* @param text the assertion's source text
* @param recorder a recorder holding the values recorded during evaluation
* of the assertion
* @return a string representation of the assertion and its recorded values
*/
public static String render(String text, ValueRecorder recorder) {
return new AssertionRenderer(text, recorder).render();
}
private String render() {
renderText();
sortValues();
renderValues();
return linesToString();
}
private void renderText() {
lines.add(new StringBuilder(text));
startColumns.add(0);
lines.add(new StringBuilder()); // empty line
startColumns.add(0);
}
private void sortValues() {
// it's important to use a stable sort here, otherwise
// renderValues() will skip the wrong values
Collections.sort(recorder.getValues(),
new Comparator<Value>() {
public int compare(Value v1, Value v2) {
return v2.getColumn() - v1.getColumn();
}
}
);
}
private void renderValues() {
List<Value> values = recorder.getValues();
nextValue:
for (int i = 0; i < values.size(); i++) {
Value value = values.get(i);
int startColumn = value.getColumn();
if (startColumn < 1) continue; // skip values with unknown source position
// if multiple values are associated with the same column, only
// render the value which was recorded last (i.e. the value
// corresponding to the outermost expression)
// important for GROOVY-4344
Value next = i + 1 < values.size() ? values.get(i + 1) : null;
if (next != null && next.getColumn() == value.getColumn()) continue;
String str = valueToString(value.getValue());
if (str == null) continue; // null signals the value shouldn't be rendered
String[] strs = str.split("\r\n|\r|\n");
int endColumn = strs.length == 1 ?
value.getColumn() + str.length() : // exclusive
Integer.MAX_VALUE; // multi-line strings are always placed on new lines
for (int j = 1; j < lines.size(); j++)
if (endColumn < startColumns.get(j)) {
placeString(lines.get(j), str, startColumn);
startColumns.set(j, startColumn);
continue nextValue;
} else {
placeString(lines.get(j), "|", startColumn);
if (j > 1) // make sure that no values are ever placed on empty line
startColumns.set(j, startColumn + 1); // + 1: no whitespace required between end of value and "|"
}
// value could not be placed on existing lines, so place it on new line(s)
for (String s : strs) {
StringBuilder newLine = new StringBuilder();
lines.add(newLine);
placeString(newLine, s, startColumn);
startColumns.add(startColumn);
}
}
}
private String linesToString() {
StringBuilder firstLine = lines.get(0);
for (int i = 1; i < lines.size(); i++)
firstLine.append('\n').append(lines.get(i).toString());
return firstLine.toString();
}
private static void placeString(StringBuilder line, String str, int column) {
while (line.length() < column)
line.append(' ');
line.replace(column - 1, column - 1 + str.length(), str);
}
/**
* Returns a string representation of the given value, or <tt>null if
* the value should not be included (because it does not add any valuable
* information).
*
* @param value a value
* @return a string representation of the given value
*/
private static String valueToString(Object value) {
String toString;
try {
toString = DefaultGroovyMethods.toString(value);
} catch (Exception e) {
return String.format("%s (toString() threw %s)",
javaLangObjectToString(value), e.getClass().getName());
}
if (toString == null) {
return String.format("%s (toString() == null)", javaLangObjectToString(value));
}
if (toString.equals("")) {
if (hasStringLikeType(value)) return "\"\"";
return String.format("%s (toString() == \"\")", javaLangObjectToString(value));
}
return toString;
}
private static boolean hasStringLikeType(Object value) {
Class<?> clazz = value.getClass();
return clazz == String.class || clazz == StringBuffer.class || clazz == StringBuilder.class;
}
private static String javaLangObjectToString(Object value) {
String hash = Integer.toHexString(System.identityHashCode(value));
return value.getClass().getName() + "@" + hash;
}
}
Other Groovy examples (source code examples)
Here is a short list of links related to this Groovy AssertionRenderer.java source code file:
|