From 605bc0154f080e7a98c70256830a7d1d620e1358 Mon Sep 17 00:00:00 2001 From: Sebb Date: Fri, 14 Jun 2019 16:32:45 +0100 Subject: [PATCH] CSV-242 CSVFormat equals() and hash() don't use all fields Fix equals() TODO fix hash() --- .../org/apache/commons/csv/CSVFormat.java | 21 +++++++ .../org/apache/commons/csv/CSVFormatTest.java | 56 +++++++++++++++++++ 2 files changed, 77 insertions(+) diff --git a/src/main/java/org/apache/commons/csv/CSVFormat.java b/src/main/java/org/apache/commons/csv/CSVFormat.java index 1f607851..05317862 100644 --- a/src/main/java/org/apache/commons/csv/CSVFormat.java +++ b/src/main/java/org/apache/commons/csv/CSVFormat.java @@ -809,6 +809,24 @@ public final class CSVFormat implements Serializable { if (delimiter != other.delimiter) { return false; } + if (trailingDelimiter != other.trailingDelimiter) { + return false; + } + if (autoFlush != other.autoFlush) { + return false; + } + if (trim != other.trim) { + return false; + } + if (allowMissingColumnNames != other.allowMissingColumnNames) { + return false; + } + if (allowDuplicateHeaderNames != other.allowDuplicateHeaderNames) { + return false; + } + if (ignoreHeaderCase != other.ignoreHeaderCase) { + return false; + } if (quoteMode != other.quoteMode) { return false; } @@ -859,6 +877,9 @@ public final class CSVFormat implements Serializable { } else if (!recordSeparator.equals(other.recordSeparator)) { return false; } + if (!Arrays.equals(headerComments, other.headerComments)) { + return false; + } return true; } diff --git a/src/test/java/org/apache/commons/csv/CSVFormatTest.java b/src/test/java/org/apache/commons/csv/CSVFormatTest.java index 2a74b6f5..c62cb583 100644 --- a/src/test/java/org/apache/commons/csv/CSVFormatTest.java +++ b/src/test/java/org/apache/commons/csv/CSVFormatTest.java @@ -34,6 +34,8 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; import java.util.Arrays; import org.junit.Assert; @@ -1108,4 +1110,58 @@ public class CSVFormatTest { assertEquals(System.getProperty("line.separator"), formatWithRecordSeparator.getRecordSeparator()); } + private void assertNotEquals(String name, String type, Object left, Object right) { + if (left.equals(right) || right.equals(left)) { + System.out.println("Should not be equal for " + name + "(" + type + ")"); + } + } + + @Test + public void testEqualsHash() throws Exception { + Method[] methods = CSVFormat.class.getDeclaredMethods(); + for (Method method : methods) { + if (Modifier.isPublic(method.getModifiers())) { + final String name = method.getName(); + if (name.startsWith("with")) { + for (Class cls : method.getParameterTypes()) { + final String type = cls.getCanonicalName(); + if ("boolean".equals(type)) { + final Object defTrue = method.invoke(CSVFormat.DEFAULT, new Object[] {Boolean.TRUE}); + final Object defFalse = method.invoke(CSVFormat.DEFAULT, new Object[] {Boolean.FALSE}); + assertNotEquals(name, type ,defTrue, defFalse); + } else if ("char".equals(type)){ + final Object a = method.invoke(CSVFormat.DEFAULT, new Object[] {'a'}); + final Object b = method.invoke(CSVFormat.DEFAULT, new Object[] {'b'}); + assertNotEquals(name, type, a, b); + } else if ("java.lang.Character".equals(type)){ + final Object a = method.invoke(CSVFormat.DEFAULT, new Object[] {null}); + final Object b = method.invoke(CSVFormat.DEFAULT, new Object[] {new Character('d')}); + assertNotEquals(name, type, a, b); + } else if ("java.lang.String".equals(type)){ + final Object a = method.invoke(CSVFormat.DEFAULT, new Object[] {null}); + final Object b = method.invoke(CSVFormat.DEFAULT, new Object[] {"e"}); + assertNotEquals(name, type, a, b); + } else if ("java.lang.String[]".equals(type)){ + final Object a = method.invoke(CSVFormat.DEFAULT, new Object[] {new String[] {null, null}}); + final Object b = method.invoke(CSVFormat.DEFAULT, new Object[] {new String[] {"f", "g"}}); + assertNotEquals(name, type, a, b); + } else if ("org.apache.commons.csv.QuoteMode".equals(type)){ + final Object a = method.invoke(CSVFormat.DEFAULT, new Object[] {QuoteMode.MINIMAL}); + final Object b = method.invoke(CSVFormat.DEFAULT, new Object[] {QuoteMode.ALL}); + assertNotEquals(name, type, a, b); + } else if ("java.lang.Object[]".equals(type)){ + final Object a = method.invoke(CSVFormat.DEFAULT, new Object[] {new Object[] {null, null}}); + final Object b = method.invoke(CSVFormat.DEFAULT, new Object[] {new Object[] {new Object(), new Object()}}); + assertNotEquals(name, type, a, b); + } else if ("withHeader".equals(name)){ // covered above by String[] + // ignored + } else { + fail("Unhandled method: "+name + "(" + type + ")"); + } + } + } + } + } + } + }