| /* |
| * Copyright (c) 2016 Mockito contributors |
| * This program is made available under the terms of the MIT License. |
| */ |
| package org.mockito.internal.matchers.text; |
| |
| import java.util.Iterator; |
| import java.util.Map; |
| |
| import static java.lang.String.valueOf; |
| |
| /** |
| * Prints a Java object value in a way humans can read it neatly. |
| * Inspired on hamcrest. Used for printing arguments in verification errors. |
| */ |
| public class ValuePrinter { |
| |
| private ValuePrinter(){} |
| |
| /** |
| * Prints given value so that it is neatly readable by humans. |
| * Handles explosive toString() implementations. |
| */ |
| public static String print(Object value) { |
| if (value == null) { |
| return "null"; |
| } |
| if (value instanceof String) { |
| return '"' + value.toString() + '"'; |
| } |
| if (value instanceof Character) { |
| return printChar((Character) value); |
| } |
| if (value instanceof Long) { |
| return value + "L"; |
| } |
| if (value instanceof Double) { |
| return value + "d"; |
| } |
| if (value instanceof Float) { |
| return value + "f"; |
| } |
| if (value instanceof Short) { |
| return "(short) " + value; |
| } |
| if (value instanceof Byte) { |
| return String.format("(byte) 0x%02X", (Byte) value); |
| } |
| if (value instanceof Map) { |
| return printMap((Map<?, ?>) value); |
| } |
| if (value.getClass().isArray()) { |
| return printValues("[", ", ", "]", new ArrayIterator(value)); |
| } |
| if (value instanceof FormattedText) { |
| return (((FormattedText) value).getText()); |
| } |
| |
| return descriptionOf(value); |
| } |
| |
| private static String printMap(Map<?,?> map) { |
| StringBuilder result = new StringBuilder(); |
| Iterator<? extends Map.Entry<?, ?>> iterator = map.entrySet().iterator(); |
| while (iterator.hasNext()) { |
| Map.Entry<?, ?> entry = iterator.next(); |
| result.append(print(entry.getKey())).append(" = ").append(print(entry.getValue())); |
| if (iterator.hasNext()) { |
| result.append(", "); |
| } |
| } |
| return "{" + result.toString() + "}"; |
| } |
| |
| /** |
| * Print values in a nice format, e.g. (1, 2, 3) |
| * |
| * @param start the beginning of the values, e.g. "(" |
| * @param separator the separator of values, e.g. ", " |
| * @param end the end of the values, e.g. ")" |
| * @param values the values to print |
| * |
| * @return neatly formatted value list |
| */ |
| public static String printValues(String start, String separator, String end, Iterator<?> values) { |
| if(start == null){ |
| start = "("; |
| } |
| if (separator == null){ |
| separator = ","; |
| } |
| if (end == null){ |
| end = ")"; |
| } |
| |
| StringBuilder sb = new StringBuilder(start); |
| while(values.hasNext()) { |
| sb.append(print(values.next())); |
| if (values.hasNext()) { |
| sb.append(separator); |
| } |
| } |
| return sb.append(end).toString(); |
| } |
| |
| private static String printChar(char value) { |
| StringBuilder sb = new StringBuilder(); |
| sb.append('\''); |
| switch (value) { |
| case '"': |
| sb.append("\\\""); |
| break; |
| case '\n': |
| sb.append("\\n"); |
| break; |
| case '\r': |
| sb.append("\\r"); |
| break; |
| case '\t': |
| sb.append("\\t"); |
| break; |
| default: |
| sb.append(value); |
| } |
| sb.append('\''); |
| return sb.toString(); |
| } |
| |
| private static String descriptionOf(Object value) { |
| try { |
| return valueOf(value); |
| } |
| catch (Exception e) { |
| return value.getClass().getName() + "@" + Integer.toHexString(value.hashCode()); |
| } |
| } |
| } |