This is an automated email from the ASF dual-hosted git repository.

aherbert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-csv.git

commit 8d6772a3209b124af7e2430f69cdf6a7c765fd44
Author: aherbert <aherb...@apache.org>
AuthorDate: Tue Jan 21 12:22:48 2020 +0000

    [CSV-248] Test the parser and map functionality after deserialization
    
    Methods with unexpected return values (null or exceptions) have been
    documented. All other methods will just fail as if the record came from
    a parser without a header.
---
 .../java/org/apache/commons/csv/CSVRecord.java     | 13 +++++-
 .../java/org/apache/commons/csv/CSVRecordTest.java | 50 +++++++++++++++++++++-
 2 files changed, 60 insertions(+), 3 deletions(-)

diff --git a/src/main/java/org/apache/commons/csv/CSVRecord.java 
b/src/main/java/org/apache/commons/csv/CSVRecord.java
index 471e94d..e32cd5a 100644
--- a/src/main/java/org/apache/commons/csv/CSVRecord.java
+++ b/src/main/java/org/apache/commons/csv/CSVRecord.java
@@ -83,6 +83,12 @@ public final class CSVRecord implements Serializable, 
Iterable<String> {
     /**
      * Returns a value by name.
      *
+     * <p>Note: This requires a field mapping obtained from the original 
parser.
+     * A check using {@link #isMapped(String)} should be used to determine if a
+     * mapping exists from the provide {@code name} to a field index. In this 
case an
+     * exception will only be thrown if the record does not contain a field 
corresponding
+     * to the mapping, that is the record length is not consistent with the 
mapping size.
+     *
      * @param name
      *            the name of the column to be retrieved.
      * @return the column value, maybe null depending on {@link 
CSVFormat#getNullString()}.
@@ -90,7 +96,9 @@ public final class CSVRecord implements Serializable, 
Iterable<String> {
      *             if no header mapping was provided
      * @throws IllegalArgumentException
      *             if {@code name} is not mapped or if the record is 
inconsistent
+     * @see #isMapped(String)
      * @see #isConsistent()
+     * @see #getParser()
      * @see CSVFormat#withNullString(String)
      */
     public String get(final String name) {
@@ -136,12 +144,15 @@ public final class CSVRecord implements Serializable, 
Iterable<String> {
     }
 
     private Map<String, Integer> getHeaderMapRaw() {
-        return parser.getHeaderMapRaw();
+        return parser == null ? null : parser.getHeaderMapRaw();
     }
 
     /**
      * Returns the parser.
      *
+     * <p>Note: The parser is not part of the serialized state of the record. 
A null check
+     * should be used when the record may have originated from a serialized 
form. 
+     *
      * @return the parser.
      * @since 1.7
      */
diff --git a/src/test/java/org/apache/commons/csv/CSVRecordTest.java 
b/src/test/java/org/apache/commons/csv/CSVRecordTest.java
index 476bac2..8d11d53 100644
--- a/src/test/java/org/apache/commons/csv/CSVRecordTest.java
+++ b/src/test/java/org/apache/commons/csv/CSVRecordTest.java
@@ -23,12 +23,15 @@ import static org.junit.jupiter.api.Assertions.assertNull;
 import static org.junit.jupiter.api.Assertions.assertThrows;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
+import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
+import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
 import java.io.StringReader;
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.Map;
 import java.util.TreeMap;
 import java.util.concurrent.ConcurrentHashMap;
@@ -192,15 +195,58 @@ public class CSVRecordTest {
     }
 
     @Test
-    public void testSerialization() throws IOException {
+    public void testSerialization() throws IOException, ClassNotFoundException 
{
         CSVRecord shortRec;
-        try (final CSVParser parser = CSVParser.parse("a,b", 
CSVFormat.newFormat(','))) {
+        try (final CSVParser parser = CSVParser.parse("A,B\n#my 
comment\nOne,Two", CSVFormat.DEFAULT.withHeader().withCommentMarker('#'))) {
             shortRec = parser.iterator().next();
         }
         final ByteArrayOutputStream out = new ByteArrayOutputStream();
         try (ObjectOutputStream oos = new ObjectOutputStream(out)) {
             oos.writeObject(shortRec);
         }
+        final ByteArrayInputStream in = new 
ByteArrayInputStream(out.toByteArray());
+        try (ObjectInputStream ois = new ObjectInputStream(in)) {
+            final Object object = ois.readObject();
+            assertTrue(object instanceof CSVRecord);
+            final CSVRecord rec = (CSVRecord) object;
+            assertEquals(1L, rec.getRecordNumber());
+            assertEquals("One", rec.get(0));
+            assertEquals("Two", rec.get(1));
+            assertEquals(2, rec.size());
+            assertEquals(shortRec.getCharacterPosition(), 
rec.getCharacterPosition());
+            assertEquals("my comment", rec.getComment());
+            // The parser is not serialized
+            assertNull(rec.getParser());
+            // Check all header map functionality is absent
+            assertTrue(rec.isConsistent());
+            assertFalse(rec.isMapped("A"));
+            assertFalse(rec.isSet("A"));
+            assertEquals(0, rec.toMap().size());
+            // This will throw
+            try {
+                rec.get("A");
+                org.junit.jupiter.api.Assertions.fail("Access by name is not 
expected after deserialisation");
+            } catch (IllegalStateException expected) {
+                // OK
+            }
+        }
+    }
+
+    /**
+     * Test deserialisation of a record created using version 1.6.
+     *
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    @Test
+    public void testDeserialisation() throws IOException {
+        CSVRecord shortRec;
+        try (final CSVParser parser = CSVParser.parse("A,B\n#my 
comment\nOne,Two", CSVFormat.DEFAULT.withHeader().withCommentMarker('#'))) {
+            shortRec = parser.iterator().next();
+        }
+        try (FileOutputStream out = new FileOutputStream("/tmp/csvRecord.ser");
+            ObjectOutputStream oos = new ObjectOutputStream(out)) {
+            oos.writeObject(shortRec);
+        }
     }
 
     @Test

Reply via email to