Assertj-core: better failure message for endswith

Created on 20 Mar 2019  路  8Comments  路  Source: assertj/assertj-core

given a very long list, a ... is used to represent the end of the list, however this isn't really useful when calling .endsWith, suggest displaying a tail of the list instead

    2019-03-19T22:42:27.999,
    ...]>
to end with:
 <[2019-03-19T22:42:27.009990]>
improvement

All 8 comments

I don't want to print a list with 1100 elements ;) though honestly I may use this to set it shorter, I think it shows too many now.

you can check the last element directly I guess then, not as classy as endsWith but will get the job done.

@joel-costigliola What we should do here? I think we can change the failure message by rewrite format(Object[] array, String elementSeparator, String indentation, Set<Object[]> alreadyFormatted), and thus print both the head and tail of the list. For example, if maxElementsForPrinting is 3, the result can be

<["First",
    3,
    "foo",
    ...,
    "foo",
    3,
    "last"]>

That's a good idea!

@joel-costigliola I'm going to rewrite this method String format(Object[] array, String elementSeparator, String indentation, Set<Object[]> alreadyFormatted) which belongs to presentation/StandardRepresentation.javaas follows. What do you think?

  protected String convertObjectToString(Object element, String elementSeparator,
                                         String indentation, Set<Object[]> alreadyFormatted) {
    if (!isArray(element))
      return element == null ? NULL : toStringOf(element);
    else if (isArrayTypePrimitive(element))
      return formatPrimitiveArray(element);
    else if (alreadyFormatted.contains(element))
      return "(this array)";
    return format((Object[]) element, elementSeparator, indentation, alreadyFormatted);
  }

  protected String[] formatShortArray(Object[] array, String elementSeparator,
                                      String indentation, Set<Object[]> alreadyFormatted) {
    String[] elementDescriptions = new String[1 + array.length];
    for (int i = 0; i < array.length; i++)
      elementDescriptions[i] = convertObjectToString(array[i], elementSeparator, indentation, alreadyFormatted);
    return elementDescriptions;
  }

  protected String[] formatLongArray(Object[] array, String elementSeparator,
                                     String indentation, Set<Object[]> alreadyFormatted) {
    String[] elementDescriptions = new String[1 + 2 * maxElementsForPrinting];
    for (int i = 0; i < maxElementsForPrinting; i++) {
      elementDescriptions[i] = convertObjectToString(array[i], elementSeparator, indentation, alreadyFormatted);
      elementDescriptions[2 * maxElementsForPrinting - i] = convertObjectToString(array[array.length - i - 1], elementSeparator,
                                                                                  indentation, alreadyFormatted);
    }
    elementDescriptions[maxElementsForPrinting] = DEFAULT_MAX_ELEMENTS_EXCEEDED;
    return elementDescriptions;
  }

  protected String format(Object[] array, String elementSeparator,
                          String indentation, Set<Object[]> alreadyFormatted) {
    if (array == null) return null;
    if (array.length == 0) return DEFAULT_START + DEFAULT_END;

    alreadyFormatted.add(array); // used to avoid infinite recursion when array contains itself
    // iterable has some elements
    String[] elementDescriptions = (array.length <= 2 * maxElementsForPrinting)
        ? formatShortArray(array, elementSeparator, indentation, alreadyFormatted)
        : formatLongArray(array, elementSeparator, indentation, alreadyFormatted);

    StringBuilder desc = new StringBuilder();
    desc.append(DEFAULT_START);
    for (int i = 0; i < elementDescriptions.length; i++) {
      if (i != 0) desc.append(indentation);
      String elementDescription = elementDescriptions[i];
      desc.append(elementDescription);
      if (i != elementDescriptions.length - 1) desc.append(elementSeparator);
    }
    alreadyFormatted.remove(array);
    return desc.append(DEFAULT_END).toString();
  }

It was originally like this:

  protected String format(Object[] array, String elementSeparator,
                          String indentation, Set<Object[]> alreadyFormatted) {
    if (array == null) return null;
    if (array.length == 0) return DEFAULT_START + DEFAULT_END;
    // iterable has some elements
    StringBuilder desc = new StringBuilder();
    desc.append(DEFAULT_START);
    alreadyFormatted.add(array); // used to avoid infinite recursion when array contains itself
    int i = 0;
    while (true) {
      Object element = array[i];
      // do not indent first element
      if (i != 0) desc.append(indentation);
      if (i == maxElementsForPrinting) {
        desc.append(DEFAULT_MAX_ELEMENTS_EXCEEDED);
        alreadyFormatted.remove(array);
        return desc.append(DEFAULT_END).toString();
      }
      // add element representation
      if (!isArray(element)) desc.append(element == null ? NULL : toStringOf(element));
      else if (isArrayTypePrimitive(element)) desc.append(formatPrimitiveArray(element));
      else if (alreadyFormatted.contains(element)) desc.append("(this array)");
      else desc.append(format((Object[]) element, elementSeparator, indentation, alreadyFormatted));
      // manage end description
      if (i == array.length - 1) {
        alreadyFormatted.remove(array);
        return desc.append(DEFAULT_END).toString();
      }
      // there are still elements to describe
      desc.append(elementSeparator);
      i++;
    }
  }

You will have to, go for it.

Was this page helpful?
0 / 5 - 0 ratings