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

zeroshade pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow-go.git


The following commit(s) were added to refs/heads/main by this push:
     new c0d32bdf test: make JSON tests independent of the JSON backend's error 
details (#1428)
c0d32bdf is described below

commit c0d32bdfbb2a2f7410e3714c3671ec81320f2b9c
Author: Matt Topol <[email protected]>
AuthorDate: Tue Oct 27 17:04:55 2026 +0000

    test: make JSON tests independent of the JSON backend's error details 
(#1428)
    
    ### Rationale for this change
    
    The Dependabot bump of `github.com/goccy/go-json` to v0.11.2 (#1357)
    fails CI. go-json 0.11 is stricter and follows `encoding/json`'s
    behaviour for the Go version it is built with, which exposed three tests
    that depended on lenient parsing or on backend-specific error details:
    
    - `arrow/compute` `TestIsInDecimal`: the expected array literal is
    `[true, false true]` (missing comma); go-json 0.10 accepted it.
    - `arrow/array` `TestIntegerArrsJSON` and
    `TestRecordBuilderUnmarshalOneReturnUnexpectedEOF`: under Go 1.27's v2
    JSON semantics, truncated input is reported as a syntax error
    ("unexpected end of JSON input") instead of `io.ErrUnexpectedEOF`.
    - `parquet/variant` `TestBuilderJSONErrors`: the error message depends
    on which tokenizer call first notices the malformed input.
    
    The last two already fail on `main` with the standard-library backend
    (`-tags arrow_json_stdlib`, also used for TinyGo) under Go 1.27,
    independent of the bump.
    
    ### What changes are included in this PR?
    
    Test-only:
    
    - Fix the JSON literal in `TestIsInDecimal`.
    - A helper `assertTruncatedJSONError` checks that truncated input is an
    error and **not** a clean `io.EOF` — the invariant #1341 added — while
    accepting either `io.ErrUnexpectedEOF` or an "unexpected end of JSON
    input" syntax error.
    - `TestBuilderJSONErrors` keeps all its malformed inputs but only checks
    that `ParseJSON` rejects them.
    
    ### Are these changes tested?
    
    The affected packages (`arrow/array`, `arrow/compute`,
    `parquet/variant`) pass with Go 1.26 and Go 1.27, each with go-json
    v0.10.6, go-json v0.11.2 and `-tags arrow_json_stdlib`. Disabling the
    `io.EOF` → `io.ErrUnexpectedEOF` conversion in
    `RecordBuilder.unmarshalOne` still fails
    `TestRecordBuilderUnmarshalOneReturnUnexpectedEOF` ("truncated input
    must not be reported as a clean EOF").
    
    ### Are there any user-facing changes?
    
    No.
---
 arrow/array/util_test.go                | 17 ++++++++++++++--
 arrow/compute/scalar_set_lookup_test.go |  2 +-
 parquet/variant/builder_test.go         | 36 +++++++++++++++++----------------
 3 files changed, 35 insertions(+), 20 deletions(-)

diff --git a/arrow/array/util_test.go b/arrow/array/util_test.go
index 652a3556..8c0bfe7a 100644
--- a/arrow/array/util_test.go
+++ b/arrow/array/util_test.go
@@ -245,7 +245,7 @@ func TestIntegerArrsJSON(t *testing.T) {
                        assert.Error(t, err)
 
                        _, _, err = array.FromJSON(memory.DefaultAllocator, tt, 
strings.NewReader("["))
-                       assert.ErrorIs(t, err, io.ErrUnexpectedEOF)
+                       assertTruncatedJSONError(t, err)
 
                        _, _, err = array.FromJSON(memory.DefaultAllocator, tt, 
strings.NewReader("0"))
                        assert.Error(t, err)
@@ -918,6 +918,19 @@ func 
TestRecordBuilderUnmarshalOnePreservesUserDecoderOptions(t *testing.T) {
        assert.EqualValues(t, int64(9223372036854775807), col.Value(0))
 }
 
+// assertTruncatedJSONError checks that truncated JSON input is reported as an
+// error rather than as a clean end of input. JSON backends differ in how they
+// report truncation: encoding/json before Go 1.27's v2 semantics (and go-json
+// before v0.11) surface io.ErrUnexpectedEOF, while the v2 semantics report a
+// syntax error describing the unexpected end of input.
+func assertTruncatedJSONError(t *testing.T, err error) {
+       t.Helper()
+       require.Error(t, err)
+       assert.False(t, errors.Is(err, io.EOF), "truncated input must not be 
reported as a clean EOF: %v", err)
+       assert.True(t, errors.Is(err, io.ErrUnexpectedEOF) || 
strings.Contains(err.Error(), "unexpected end of JSON input"),
+               "expected an unexpected-end-of-input error, got %v", err)
+}
+
 func TestRecordBuilderUnmarshalOneReturnUnexpectedEOF(t *testing.T) {
        mem := memory.NewCheckedAllocator(memory.DefaultAllocator)
        defer mem.AssertSize(t, 0)
@@ -932,7 +945,7 @@ func TestRecordBuilderUnmarshalOneReturnUnexpectedEOF(t 
*testing.T) {
        src := strings.NewReader(`{"a": 9`)
        dec := json.NewDecoder(src)
 
-       assert.ErrorIs(t, bldr.UnmarshalOne(dec), io.ErrUnexpectedEOF)
+       assertTruncatedJSONError(t, bldr.UnmarshalOne(dec))
 }
 
 func TestDurationBuilderJSONStringInteger(t *testing.T) {
diff --git a/arrow/compute/scalar_set_lookup_test.go 
b/arrow/compute/scalar_set_lookup_test.go
index 18b9a78e..5ddd2875 100644
--- a/arrow/compute/scalar_set_lookup_test.go
+++ b/arrow/compute/scalar_set_lookup_test.go
@@ -355,7 +355,7 @@ func (ss *ScalarSetLookupSuite) TestIsInDecimal() {
                                values := ss.getArr(typ, `["12.3", "78.9"]`)
                                defer values.Release()
 
-                               ss.checkIsIn(in, values, `[true, false true]`, 
compute.NullMatchingMatch)
+                               ss.checkIsIn(in, values, `[true, false, true]`, 
compute.NullMatchingMatch)
                        }
                })
        }
diff --git a/parquet/variant/builder_test.go b/parquet/variant/builder_test.go
index 982fa4e9..98a4d7f7 100644
--- a/parquet/variant/builder_test.go
+++ b/parquet/variant/builder_test.go
@@ -826,31 +826,33 @@ func TestBuilderFromJSON(t *testing.T) {
        }
 }
 
+// TestBuilderJSONErrors checks that malformed JSON is rejected. The detailed
+// message depends on which JSON backend and Go version tokenizes the input,
+// so only the error wrapping added by ParseJSON is checked.
 func TestBuilderJSONErrors(t *testing.T) {
        tests := []struct {
-               name    string
-               input   string
-               wantErr string
+               name  string
+               input string
        }{
-               {"empty string", ``, "unexpected end of JSON input"},
-               {"invalid token", `a`, "failed to decode JSON token"},
-               {"missing array end", `[1, 2, 3`, "failed to decode JSON array 
end"},
-               {"invalid array", `[1, "foo", bar`, "failed to decode JSON 
token"},
-               {"missing elem", `[1,`, "unexpected end of JSON input"},
-               {"invalid elem", `[1, 5 }`, "expected end of JSON array, got 
}"},
-               {"extra delimiter", `]`, "unexpected JSON delimiter"},
-               {"invalid key", `{"key": "value", 42: "invalid"}`, "expected 
string key in JSON object"},
-               {"eof key", `{"key": 1,`, "unexpected end of JSON input"},
-               {"invalid token key", `{ab`, "failed to decode JSON key"},
-               {"invalid object", `{"key": foo}`, "failed to decode JSON 
token"},
-               {"invalid object end", `{"key": 123 ]`, "expected end of JSON 
object"},
-               {"missing object end", `{"key": 123`, "failed to decode JSON 
object end"},
+               {"empty string", ``},
+               {"invalid token", `a`},
+               {"missing array end", `[1, 2, 3`},
+               {"invalid array", `[1, "foo", bar`},
+               {"missing elem", `[1,`},
+               {"invalid elem", `[1, 5 }`},
+               {"extra delimiter", `]`},
+               {"invalid key", `{"key": "value", 42: "invalid"}`},
+               {"eof key", `{"key": 1,`},
+               {"invalid token key", `{ab`},
+               {"invalid object", `{"key": foo}`},
+               {"invalid object end", `{"key": 123 ]`},
+               {"missing object end", `{"key": 123`},
        }
 
        for _, tt := range tests {
                t.Run(tt.name, func(t *testing.T) {
                        _, err := variant.ParseJSON(tt.input, false)
-                       assert.ErrorContains(t, err, tt.wantErr)
+                       assert.ErrorContains(t, err, "failed to parse JSON")
                })
        }
 }

Reply via email to