From 2936b9d8d62717dbf9691af25d8614ac8ed006b1 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 8 Jun 2026 23:03:17 +0000 Subject: [PATCH 1/2] decode: retain incomplete trailing cell/row at EOF Non-resumable decode (whole-string) now flushes a trailing cell and an unterminated final row when the input lacks the terminal double newline, matching the spec's abrupt-EOF rule and the python/rust/js/duckdb implementations. The streaming Reader is unchanged (it must keep buffering). --- src/main/java/org/nsvformat/Nsv.java | 7 +++++++ src/test/java/org/nsvformat/DecodeTest.java | 11 +++++++++++ 2 files changed, 18 insertions(+) diff --git a/src/main/java/org/nsvformat/Nsv.java b/src/main/java/org/nsvformat/Nsv.java index ce2b268..32d9530 100644 --- a/src/main/java/org/nsvformat/Nsv.java +++ b/src/main/java/org/nsvformat/Nsv.java @@ -24,6 +24,13 @@ public static List> decode(String s) { } } + if (start < s.length()) { + row.add(unescape(s.substring(start))); + } + if (!row.isEmpty()) { + data.add(row); + } + return data; } diff --git a/src/test/java/org/nsvformat/DecodeTest.java b/src/test/java/org/nsvformat/DecodeTest.java index e49c4ce..340eb96 100644 --- a/src/test/java/org/nsvformat/DecodeTest.java +++ b/src/test/java/org/nsvformat/DecodeTest.java @@ -114,4 +114,15 @@ public void testDecodeOneOne() { List> expected = List.of(List.of("")); assertEquals(expected, Nsv.decode(input)); } + + @Test + public void testDecodeNoTrailingNewline() { + // Abrupt EOF: non-resumable decode emits the incomplete trailing cell/row + String input = "a\nb\nc\n\nd\ne\nf"; + List> expected = List.of( + List.of("a", "b", "c"), + List.of("d", "e", "f") + ); + assertEquals(expected, Nsv.decode(input)); + } } From 7756e52ae340c10bc4d6ba0ed187b5fe2f3e1b83 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 8 Jun 2026 23:21:21 +0000 Subject: [PATCH 2/2] test: drop noise comment --- src/test/java/org/nsvformat/DecodeTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/java/org/nsvformat/DecodeTest.java b/src/test/java/org/nsvformat/DecodeTest.java index 340eb96..3df34a0 100644 --- a/src/test/java/org/nsvformat/DecodeTest.java +++ b/src/test/java/org/nsvformat/DecodeTest.java @@ -117,7 +117,6 @@ public void testDecodeOneOne() { @Test public void testDecodeNoTrailingNewline() { - // Abrupt EOF: non-resumable decode emits the incomplete trailing cell/row String input = "a\nb\nc\n\nd\ne\nf"; List> expected = List.of( List.of("a", "b", "c"),