SHL-126 - Add utility classes for rendering ascii based tables

This commit is contained in:
mpollack
2014-04-01 23:50:55 -04:00
parent 8d13a494a5
commit 65c02b778b
13 changed files with 1210 additions and 0 deletions

View File

@@ -30,6 +30,7 @@ dependencies {
compile "org.springframework:spring-core:$springVersion"
compile "org.springframework:spring-context-support:$springVersion"
compile "commons-io:commons-io:$commonsioVersion"
compile "com.google.guava:guava:15.0"
compile "jline:jline:$jlineVersion"
compile "cglib:cglib:$cglibVersion"

View File

@@ -0,0 +1,130 @@
/*
* Copyright 2009-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.springframework.shell.support.table;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
/**
* Provide a basic concept of a table structure containing a map of column
* headers and a collection of rows. Used to render text-based tables (console
* output).
*
* @see TableRenderer
*
* @author Gunnar Hillert
*
*/
public class Table {
private final Map<Integer, TableHeader> headers = new TreeMap<Integer, TableHeader>();
private volatile List<TableRow> rows = new ArrayList<TableRow>(0);
public List<TableRow> getRows() {
return rows;
}
public Map<Integer, TableHeader> getHeaders() {
return headers;
}
public Table addHeader(Integer columnIndex, TableHeader tableHeader) {
this.headers.put(columnIndex, tableHeader);
return this;
}
/**
* Add a new empty row to the table.
*
* @return the newly created row, which can be then be populated
*/
public TableRow newRow() {
TableRow row = new TableRow();
rows.add(row);
return row;
}
public Table addRow(String... values) {
final TableRow row = new TableRow();
int column = 1;
for (String value : values) {
row.addValue(column, value);
column++;
}
rows.add(row);
return this;
}
public void calculateColumnWidths() {
for (java.util.Map.Entry<Integer, TableHeader> headerEntry : headers
.entrySet()) {
final Integer headerEntryKey = headerEntry.getKey();
for (TableRow tableRow : rows) {
headerEntry.getValue().updateWidth(
tableRow.getValue(headerEntryKey).length());
}
}
}
@Override
public String toString() {
return TableRenderer.renderTextTable(this);
}
@Override
public int hashCode() {
calculateColumnWidths();
final int prime = 31;
int result = 1;
result = prime * result + ((headers == null) ? 0 : headers.hashCode());
result = prime * result + ((rows == null) ? 0 : rows.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Table other = (Table) obj;
this.calculateColumnWidths();
other.calculateColumnWidths();
if (headers == null) {
if (other.headers != null)
return false;
} else if (!headers.equals(other.headers))
return false;
if (rows == null) {
if (other.rows != null)
return false;
} else if (!rows.equals(other.rows))
return false;
return true;
}
}

View File

@@ -0,0 +1,146 @@
/*
* Copyright 2009-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.springframework.shell.support.table;
/**
* Defines table column headers used by {@link Table}.
*
* @see TableRenderer
*
* @author Gunnar Hillert
*
*/
public class TableHeader {
private int maxWidth = -1;
private int width = 0;
private String name;
/**
* Constructor that initializes the table header with the provided header
* name and the with of the table header.
*
* @param name
* @param width
*/
public TableHeader(String name, int width) {
super();
this.width = width;
this.name = name;
}
/**
* Constructor that initializes the table header with the provided header
* name. The with of the table header is calculated and assigned based on
* the provided header name.
*
* @param name
*/
public TableHeader(String name) {
super();
this.name = name;
if (name == null) {
this.width = 0;
} else {
this.width = name.length();
}
}
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
/**
* Updated the width for this particular column, but only if the value of
* the passed-in width is higher than the value of the pre-existing width.
*
* @param width
*/
public void updateWidth(int width) {
if (this.width < width) {
if (this.maxWidth > 0 && this.maxWidth < width) {
this.width = this.maxWidth;
} else {
this.width = width;
}
}
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getMaxWidth() {
return maxWidth;
}
/**
* Defaults to -1 indicating to ignore the property.
*
* @param maxWidth
* If negative or zero this property will be ignored.
*/
public void setMaxWidth(int maxWidth) {
this.maxWidth = maxWidth;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + maxWidth;
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + width;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
TableHeader other = (TableHeader) obj;
if (maxWidth != other.maxWidth)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (width != other.width)
return false;
return true;
}
}

View File

@@ -0,0 +1,267 @@
/*
* Copyright 2009-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.springframework.shell.support.table;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.springframework.shell.support.util.StringUtils;
import com.google.common.base.Splitter;
/**
* Contains utility methods for rendering data to a formatted console output.
* E.g. it provides helper methods for rendering ASCII-based data tables.
*
* @author Gunnar Hillert
* @author Thomas Risberg
*
*/
public final class TableRenderer {
public static final String HORIZONTAL_LINE = "-------------------------------------------------------------------------------\n";
public static final int COLUMN_1 = 1;
public static final int COLUMN_2 = 2;
public static final int COLUMN_3 = 3;
public static final int COLUMN_4 = 4;
public static final int COLUMN_5 = 5;
public static final int COLUMN_6 = 6;
/**
* Prevent instantiation.
*
*/
private TableRenderer() {
throw new AssertionError();
}
/**
* Renders a textual representation of the list of provided Map data
*
* @param columns
* List of Maps
* @return The rendered table representation as String
*
*/
public static String renderMapDataAsTable(List<Map<String, Object>> data,
List<String> columns) {
Table table = new Table();
int col = 0;
for (String colName : columns) {
col++;
table.getHeaders().put(col, new TableHeader(colName));
if (col >= 6) {
break;
}
}
for (Map<String, Object> dataRow : data) {
TableRow tableRow = new TableRow();
for (int i = 0; i < col; i++) {
String value = dataRow.get(columns.get(i)).toString();
table.getHeaders().get(i + 1).updateWidth(value.length());
tableRow.addValue(i + 1, value);
}
table.getRows().add(tableRow);
}
return renderTextTable(table);
}
public static String renderParameterInfoDataAsTable(
Map<String, String> parameters, boolean withHeader,
int lastColumnMaxWidth) {
final Table table = new Table();
table.getHeaders().put(COLUMN_1, new TableHeader("Parameter"));
final TableHeader tableHeader2 = new TableHeader(
"Value (Configured or Default)");
tableHeader2.setMaxWidth(lastColumnMaxWidth);
table.getHeaders().put(COLUMN_2, tableHeader2);
for (Entry<String, String> entry : parameters.entrySet()) {
final TableRow tableRow = new TableRow();
table.getHeaders().get(COLUMN_1)
.updateWidth(entry.getKey().length());
tableRow.addValue(COLUMN_1, entry.getKey());
int width = entry.getValue() != null ? entry.getValue().length()
: 0;
table.getHeaders().get(COLUMN_2).updateWidth(width);
tableRow.addValue(COLUMN_2, entry.getValue());
table.getRows().add(tableRow);
}
return renderTextTable(table, withHeader);
}
/**
* Renders a textual representation of provided parameter map.
*
* @param parameters
* Map of parameters (key, value)
* @return The rendered table representation as String
*
*/
public static String renderParameterInfoDataAsTable(
Map<String, String> parameters) {
return renderParameterInfoDataAsTable(parameters, true, -1);
}
public static String renderTextTable(Table table) {
return renderTextTable(table, true);
}
/**
* Renders a textual representation of the provided {@link Table}
*
* @param table
* Table data {@link Table}
* @return The rendered table representation as String
*/
public static String renderTextTable(Table table, boolean withHeader) {
table.calculateColumnWidths();
final String padding = " ";
final String headerBorder = getHeaderBorder(table.getHeaders());
final StringBuilder textTable = new StringBuilder();
if (withHeader) {
final StringBuilder headerline = new StringBuilder();
for (TableHeader header : table.getHeaders().values()) {
if (header.getName().length() > header.getWidth()) {
Iterable<String> chunks = Splitter.fixedLength(
header.getWidth()).split(header.getName());
int length = headerline.length();
boolean first = true;
for (String chunk : chunks) {
final String lineToAppend;
if (first) {
lineToAppend = padding
+ StringUtils.padRight(chunk,
header.getWidth());
} else {
lineToAppend = StringUtils.padLeft("", length)
+ padding
+ StringUtils.padRight(chunk,
header.getWidth());
}
first = false;
headerline.append(lineToAppend);
headerline.append("\n");
}
headerline.deleteCharAt(headerline.lastIndexOf("\n"));
} else {
String lineToAppend = padding
+ StringUtils.padRight(header.getName(),
header.getWidth());
headerline.append(lineToAppend);
}
}
textTable.append(org.springframework.util.StringUtils
.trimTrailingWhitespace(headerline.toString()));
textTable.append("\n");
}
textTable.append(headerBorder);
for (TableRow row : table.getRows()) {
StringBuilder rowLine = new StringBuilder();
for (Entry<Integer, TableHeader> entry : table.getHeaders()
.entrySet()) {
String value = row.getValue(entry.getKey());
if (value.length() > entry.getValue().getWidth()) {
Iterable<String> chunks = Splitter.fixedLength(
entry.getValue().getWidth()).split(value);
int length = rowLine.length();
boolean first = true;
for (String chunk : chunks) {
final String lineToAppend;
if (first) {
lineToAppend = padding
+ StringUtils.padRight(chunk, entry
.getValue().getWidth());
} else {
lineToAppend = StringUtils.padLeft("", length)
+ padding
+ StringUtils.padRight(chunk, entry
.getValue().getWidth());
}
first = false;
rowLine.append(lineToAppend);
rowLine.append("\n");
}
rowLine.deleteCharAt(rowLine.lastIndexOf("\n"));
} else {
String lineToAppend = padding
+ StringUtils.padRight(value, entry.getValue()
.getWidth());
rowLine.append(lineToAppend);
}
}
textTable.append(org.springframework.util.StringUtils
.trimTrailingWhitespace(rowLine.toString()));
textTable.append("\n");
}
if (!withHeader) {
textTable.append(headerBorder);
}
return textTable.toString();
}
/**
* Renders the Table header border, based on the map of provided headers.
*
* @param headers
* Map of headers containing meta information e.g. name+width of
* header
* @return Returns the rendered header border as String
*/
public static String getHeaderBorder(Map<Integer, TableHeader> headers) {
final StringBuilder headerBorder = new StringBuilder();
for (TableHeader header : headers.values()) {
headerBorder.append(StringUtils.padRight(" ",
header.getWidth() + 2, '-'));
}
headerBorder.append("\n");
return headerBorder.toString();
}
}

View File

@@ -0,0 +1,88 @@
/*
* Copyright 2009-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.springframework.shell.support.table;
import java.util.HashMap;
import java.util.Map;
/**
* Holds the table rows used by {@link Table}.
*
* @see TableRenderer
*
* @author Gunnar Hillert
* @author Ilayaperumal Gopinathan
*
*/
public class TableRow {
/** Holds the data for the column */
private Map<Integer, String> data = new HashMap<Integer, String>();
public void setData(Map<Integer, String> data) {
this.data = data;
}
/**
* Return a value from this row.
*
* @param key
* Column for which to return the value for
* @return Value of the specified column within this row
*
*/
public String getValue(Integer key) {
return data.get(key);
}
/**
* Add a value to the to the specified column within this row.
*
* @param column
* @param value
*/
public TableRow addValue(Integer column, String value) {
this.data.put(column, value);
return this;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((data == null) ? 0 : data.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
TableRow other = (TableRow) obj;
if (data == null) {
if (other.data != null)
return false;
} else if (!data.equals(other.data))
return false;
return true;
}
}

View File

@@ -0,0 +1,279 @@
/*
* Copyright 2009-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.springframework.shell.support.util;
/**
* Utility methods for Strings focused on the use in formatting of tables. padLeft methods taken from
* Commons Lang 2.6 to avoid an extra compile time dependency.
*
* @author Gunnar Hillert
* @author Mark Pollack
*
*/
public class StringUtils {
/**
* <p>
* The maximum size to which the padding constant(s) can expand.
* </p>
*/
private static final int PAD_LIMIT = 8192;
/**
* <p>
* Left pad a String with spaces (' ').
* </p>
*
* <p>
* The String is padded to the size of <code>size</code>.
* </p>
*
* <pre>
* StringUtils.leftPad(null, *) = null
* StringUtils.leftPad("", 3) = " "
* StringUtils.leftPad("bat", 3) = "bat"
* StringUtils.leftPad("bat", 5) = " bat"
* StringUtils.leftPad("bat", 1) = "bat"
* StringUtils.leftPad("bat", -1) = "bat"
* </pre>
*
* @param str
* the String to pad out, may be null
* @param size
* the size to pad to
* @return left padded String or original String if no padding is necessary,
* <code>null</code> if null String input
*/
public static String padLeft(String str, int size) {
return padLeft(str, size, ' ');
}
/**
* <p>
* Left pad a String with a specified character.
* </p>
*
* <p>
* Pad to a size of <code>size</code>.
* </p>
*
* <pre>
* StringUtils.leftPad(null, *, *) = null
* StringUtils.leftPad("", 3, 'z') = "zzz"
* StringUtils.leftPad("bat", 3, 'z') = "bat"
* StringUtils.leftPad("bat", 5, 'z') = "zzbat"
* StringUtils.leftPad("bat", 1, 'z') = "bat"
* StringUtils.leftPad("bat", -1, 'z') = "bat"
* </pre>
*
* @param str
* the String to pad out, may be null
* @param size
* the size to pad to
* @param padChar
* the character to pad with
* @return left padded String or original String if no padding is necessary,
* <code>null</code> if null String input
* @since 2.0
*/
public static String padLeft(String str, int size, char padChar) {
if (str == null) {
return null;
}
int pads = size - str.length();
if (pads <= 0) {
return str; // returns original String when possible
}
if (pads > PAD_LIMIT) {
return padLeft(str, size, String.valueOf(padChar));
}
return padding(pads, padChar).concat(str);
}
/**
* <p>
* Left pad a String with a specified String.
* </p>
*
* <p>
* Pad to a size of <code>size</code>.
* </p>
*
* <pre>
* StringUtils.leftPad(null, *, *) = null
* StringUtils.leftPad("", 3, "z") = "zzz"
* StringUtils.leftPad("bat", 3, "yz") = "bat"
* StringUtils.leftPad("bat", 5, "yz") = "yzbat"
* StringUtils.leftPad("bat", 8, "yz") = "yzyzybat"
* StringUtils.leftPad("bat", 1, "yz") = "bat"
* StringUtils.leftPad("bat", -1, "yz") = "bat"
* StringUtils.leftPad("bat", 5, null) = " bat"
* StringUtils.leftPad("bat", 5, "") = " bat"
* </pre>
*
* @param str
* the String to pad out, may be null
* @param size
* the size to pad to
* @param padStr
* the String to pad with, null or empty treated as single space
* @return left padded String or original String if no padding is necessary,
* <code>null</code> if null String input
*/
public static String padLeft(String str, int size, String padStr) {
if (str == null) {
return null;
}
if (isEmpty(padStr)) {
padStr = " ";
}
int padLen = padStr.length();
int strLen = str.length();
int pads = size - strLen;
if (pads <= 0) {
return str; // returns original String when possible
}
if (padLen == 1 && pads <= PAD_LIMIT) {
return padLeft(str, size, padStr.charAt(0));
}
if (pads == padLen) {
return padStr.concat(str);
} else if (pads < padLen) {
return padStr.substring(0, pads).concat(str);
} else {
char[] padding = new char[pads];
char[] padChars = padStr.toCharArray();
for (int i = 0; i < pads; i++) {
padding[i] = padChars[i % padLen];
}
return new String(padding).concat(str);
}
}
/**
* <p>
* Checks if a String is empty ("") or null.
* </p>
*
* <pre>
* StringUtils.isEmpty(null) = true
* StringUtils.isEmpty("") = true
* StringUtils.isEmpty(" ") = false
* StringUtils.isEmpty("bob") = false
* StringUtils.isEmpty(" bob ") = false
* </pre>
*
* <p>
* NOTE: This method changed in Lang version 2.0. It no longer trims the
* String. That functionality is available in isBlank().
* </p>
*
* @param str
* the String to check, may be null
* @return <code>true</code> if the String is empty or null
*/
public static boolean isEmpty(String str) {
return str == null || str.length() == 0;
}
/**
* <p>
* Returns padding using the specified delimiter repeated to a given length.
* </p>
*
* <pre>
* StringUtils.padding(0, 'e') = ""
* StringUtils.padding(3, 'e') = "eee"
* StringUtils.padding(-2, 'e') = IndexOutOfBoundsException
* </pre>
*
* <p>
* Note: this method doesn't not support padding with <a
* href="http://www.unicode.org/glossary/#supplementary_character">Unicode
* Supplementary Characters</a> as they require a pair of <code>char</code>s
* to be represented. If you are needing to support full I18N of your
* applications consider using {@link #repeat(String, int)} instead.
* </p>
*
* @param repeat
* number of times to repeat delim
* @param padChar
* character to repeat
* @return String with repeated character
* @throws IndexOutOfBoundsException
* if <code>repeat &lt; 0</code>
* @see #repeat(String, int)
*/
private static String padding(int repeat, char padChar)
throws IndexOutOfBoundsException {
if (repeat < 0) {
throw new IndexOutOfBoundsException(
"Cannot pad a negative amount: " + repeat);
}
final char[] buf = new char[repeat];
for (int i = 0; i < buf.length; i++) {
buf[i] = padChar;
}
return new String(buf);
}
/**
* Right-pad a String with a configurable padding character.
*
* @param inputString
* The String to pad. A {@code null} String will be treated like
* an empty String.
* @param size
* Pad String by the number of characters.
* @param paddingChar
* The character to pad the String with.
* @return The padded String. If the provided String is null, an empty
* String is returned.
*/
public static String padRight(String inputString, int size, char paddingChar) {
final String stringToPad;
if (inputString == null) {
stringToPad = "";
} else {
stringToPad = inputString;
}
StringBuilder padded = new StringBuilder(stringToPad);
while (padded.length() < size) {
padded.append(paddingChar);
}
return padded.toString();
}
/**
* Right-pad the provided String with empty spaces.
*
* @param string
* The String to pad
* @param size
* Pad String by the number of characters.
* @return The padded String. If the provided String is null, an empty
* String is returned.
*/
public static String padRight(String string, int size) {
return padRight(string, size, ' ');
}
}

View File

@@ -0,0 +1,198 @@
/*
* Copyright 2009-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.springframework.shell.support.table;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Map;
import java.util.TreeMap;
import org.junit.Test;
import org.springframework.util.FileCopyUtils;
/**
* @author Gunnar Hillert
*
*/
public class TableRendererTest {
@Test
public void testRenderTextTable() {
final Table table = new Table();
table.addHeader(1, new TableHeader("Tap Name"))
.addHeader(2, new TableHeader("Stream Name"))
.addHeader(3, new TableHeader("Tap Definition"));
for (int i = 1; i <= 3; i++) {
final TableRow row = new TableRow();
row.addValue(1, "tap" + i)
.addValue(2, "ticktock")
.addValue(3, "tap@ticktock|log");
table.getRows().add(row);
}
String expectedTableAsString = null;
final InputStream inputStream = getClass()
.getClassLoader()
.getResourceAsStream("testRenderTextTable-expected-output.txt");
assertNotNull("The inputstream is null.", inputStream);
try {
expectedTableAsString = FileCopyUtils.copyToString(new InputStreamReader(inputStream));
}
catch (IOException e) {
e.printStackTrace();
fail();
}
final String tableRenderedAsString = TableRenderer.renderTextTable(table);
assertEquals(expectedTableAsString.replaceAll("\r", ""), tableRenderedAsString);
}
@Test
public void testRenderTextTableWithSingleColumn() {
final Table table = new Table();
table.addHeader(1, new TableHeader("Gauge name"));
final TableRow row = new TableRow();
row.addValue(1, "simplegauge");
table.getRows().add(row);
String expectedTableAsString = null;
final InputStream inputStream = getClass()
.getClassLoader()
.getResourceAsStream("testRenderTextTable-single-column-expected-output.txt");
assertNotNull("The inputstream is null.", inputStream);
try {
expectedTableAsString = FileCopyUtils.copyToString(new InputStreamReader(inputStream));
}
catch (IOException e) {
e.printStackTrace();
fail();
}
final String tableRenderedAsString = TableRenderer.renderTextTable(table);
assertEquals(expectedTableAsString.replaceAll("\r", ""), tableRenderedAsString);
}
@Test
public void testRenderTextTableWithSingleColumnAndWidthOf4() {
final Table table = new Table();
final TableHeader tableHeader = new TableHeader("Gauge name");
tableHeader.setMaxWidth(4);
table.addHeader(1, tableHeader);
final TableRow row = new TableRow();
row.addValue(1, "simplegauge");
table.getRows().add(row);
String expectedTableAsString = null;
final InputStream inputStream = getClass()
.getClassLoader()
.getResourceAsStream("testRenderTextTable-single-column-width4-expected-output.txt");
assertNotNull("The inputstream is null.", inputStream);
try {
expectedTableAsString = FileCopyUtils.copyToString(new InputStreamReader(inputStream));
}
catch (IOException e) {
e.printStackTrace();
fail();
}
final String tableRenderedAsString = TableRenderer.renderTextTable(table);
assertEquals(expectedTableAsString.replaceAll("\r", ""), tableRenderedAsString);
}
@Test
public void testRenderParameterInfoDataAsTableWithMaxWidth() {
final Map<String, String> values = new TreeMap<String, String>();
values.put("Key1", "Lorem ipsum dolor sit posuere.");
values.put("My super key 2", "Lorem ipsum");
String expectedTableAsString = null;
final InputStream inputStream = getClass()
.getClassLoader()
.getResourceAsStream("testRenderParameterInfoDataAsTableWithMaxWidth.txt");
assertNotNull("The inputstream is null.", inputStream);
try {
expectedTableAsString = FileCopyUtils.copyToString(new InputStreamReader(inputStream));
}
catch (IOException e) {
e.printStackTrace();
fail();
}
final String tableRenderedAsString = TableRenderer.renderParameterInfoDataAsTable(values, false, 20);
assertEquals(expectedTableAsString.replaceAll("\r", ""), tableRenderedAsString);
}
@Test
public void testRenderTableWithRowShorthand() {
final Table table = new Table();
table.addHeader(1, new TableHeader("Property"))
.addHeader(2, new TableHeader("Value"));
table.addRow("Job Execution ID", String.valueOf(1))
.addRow("Job Name", "My Job Name")
.addRow("Start Time", "12:30")
.addRow("Step Execution Count", String.valueOf(12))
.addRow("Status", "COMPLETED");
assertNotNull(table.toString());
final InputStream inputStream = getClass()
.getClassLoader()
.getResourceAsStream("testRenderTableWithRowShorthand-expected-output.txt");
assertNotNull("The inputstream is null.", inputStream);
String expectedTableAsString = null;
try {
expectedTableAsString = FileCopyUtils.copyToString(new InputStreamReader(inputStream));
}
catch (IOException e) {
e.printStackTrace();
fail();
}
assertEquals(expectedTableAsString.replaceAll("\r", ""), table.toString());
}
}

View File

@@ -0,0 +1,74 @@
/*
* Copyright 2011-2012 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.springframework.shell.support.util;
import static org.junit.Assert.*;
import org.junit.Test;
public class StringUtilsTest {
@Test
public void testPadRightWithNullString() {
assertEquals(" ", StringUtils.padRight(null, 5));
}
@Test
public void testPadRightWithEmptyString() {
assertEquals(" ", StringUtils.padRight("", 5));
}
@Test
public void testPadRight() {
assertEquals("foo ", StringUtils.padRight("foo", 5));
}
@Test
public void testLeftPad_StringInt() {
assertEquals(null, StringUtils.padLeft(null, 5));
assertEquals(" ", StringUtils.padLeft("", 5));
assertEquals(" abc", StringUtils.padLeft("abc", 5));
assertEquals("abc", StringUtils.padLeft("abc", 2));
}
@Test
public void testLeftPad_StringIntChar() {
assertEquals(null, StringUtils.padLeft(null, 5, ' '));
assertEquals(" ", StringUtils.padLeft("", 5, ' '));
assertEquals(" abc", StringUtils.padLeft("abc", 5, ' '));
assertEquals("xxabc", StringUtils.padLeft("abc", 5, 'x'));
assertEquals("\uffff\uffffabc", StringUtils.padLeft("abc", 5, '\uffff'));
assertEquals("abc", StringUtils.padLeft("abc", 2, ' '));
String str = StringUtils.padLeft("aaa", 10000, 'a'); // bigger than pad length
assertEquals(10000, str.length());
//Note, did not include the next assert to avoid pulling in a long chain of methods from commons lang
//assertEquals(true, StringUtils.containsOnly(str, new char[] {'a'}));
}
@Test
public void testLeftPad_StringIntString() {
assertEquals(null, StringUtils.padLeft(null, 5, "-+"));
assertEquals(null, StringUtils.padLeft(null, 5, null));
assertEquals(" ", StringUtils.padLeft("", 5, " "));
assertEquals("-+-+abc", StringUtils.padLeft("abc", 7, "-+"));
assertEquals("-+~abc", StringUtils.padLeft("abc", 6, "-+~"));
assertEquals("-+abc", StringUtils.padLeft("abc", 5, "-+~"));
assertEquals("abc", StringUtils.padLeft("abc", 2, " "));
assertEquals("abc", StringUtils.padLeft("abc", -1, " "));
assertEquals(" abc", StringUtils.padLeft("abc", 5, null));
assertEquals(" abc", StringUtils.padLeft("abc", 5, ""));
}
}

View File

@@ -0,0 +1,5 @@
-------------- --------------------
Key1 Lorem ipsum dolor si
t posuere.
My super key 2 Lorem ipsum
-------------- --------------------

View File

@@ -0,0 +1,7 @@
Property Value
-------------------- -----------
Job Execution ID 1
Job Name My Job Name
Start Time 12:30
Step Execution Count 12
Status COMPLETED

View File

@@ -0,0 +1,5 @@
Tap Name Stream Name Tap Definition
-------- ----------- ----------------
tap1 ticktock tap@ticktock|log
tap2 ticktock tap@ticktock|log
tap3 ticktock tap@ticktock|log

View File

@@ -0,0 +1,3 @@
Gauge name
-----------
simplegauge

View File

@@ -0,0 +1,7 @@
Gaug
e na
me
----
simp
lega
uge