Skip to content

Commit 5da5711

Browse files
mromaszewiczclaude
andcommitted
Add tests for deepObject required/optional query parameter binding
Exercise the required and optional code paths for deepObject-style query parameters to verify no unintended side effects from PR #68. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent db20ecd commit 5da5711

File tree

1 file changed

+66
-0
lines changed

1 file changed

+66
-0
lines changed

bindparam_test.go

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,72 @@ func TestBindQueryParameter(t *testing.T) {
434434
assert.Error(t, err)
435435
})
436436

437+
t.Run("deepObject/required-and-optional", func(t *testing.T) {
438+
type SimpleObj struct {
439+
Name string `json:"name"`
440+
Age int `json:"age"`
441+
}
442+
443+
queryWithParam := url.Values{
444+
"obj[name]": {"Alice"},
445+
"obj[age]": {"30"},
446+
}
447+
emptyQuery := url.Values{}
448+
unrelatedQuery := url.Values{
449+
"other[name]": {"Bob"},
450+
}
451+
452+
t.Run("optional/present binds successfully", func(t *testing.T) {
453+
var dest SimpleObj
454+
err := BindQueryParameter("deepObject", true, false, "obj", queryWithParam, &dest)
455+
require.NoError(t, err)
456+
assert.Equal(t, SimpleObj{Name: "Alice", Age: 30}, dest)
457+
})
458+
459+
t.Run("optional/missing returns no error and does not modify dest", func(t *testing.T) {
460+
var dest SimpleObj
461+
err := BindQueryParameter("deepObject", true, false, "obj", emptyQuery, &dest)
462+
require.NoError(t, err)
463+
assert.Equal(t, SimpleObj{}, dest, "destination should remain zero-valued")
464+
})
465+
466+
t.Run("optional/missing with unrelated params returns no error", func(t *testing.T) {
467+
var dest SimpleObj
468+
err := BindQueryParameter("deepObject", true, false, "obj", unrelatedQuery, &dest)
469+
require.NoError(t, err)
470+
assert.Equal(t, SimpleObj{}, dest, "destination should remain zero-valued")
471+
})
472+
473+
t.Run("optional/missing preserves pre-populated dest", func(t *testing.T) {
474+
dest := SimpleObj{Name: "PreExisting", Age: 99}
475+
err := BindQueryParameter("deepObject", true, false, "obj", emptyQuery, &dest)
476+
require.NoError(t, err)
477+
assert.Equal(t, SimpleObj{Name: "PreExisting", Age: 99}, dest,
478+
"destination should not be zeroed out when optional param is absent")
479+
})
480+
481+
t.Run("required/present binds successfully", func(t *testing.T) {
482+
var dest SimpleObj
483+
err := BindQueryParameter("deepObject", true, true, "obj", queryWithParam, &dest)
484+
require.NoError(t, err)
485+
assert.Equal(t, SimpleObj{Name: "Alice", Age: 30}, dest)
486+
})
487+
488+
t.Run("required/missing returns error", func(t *testing.T) {
489+
var dest SimpleObj
490+
err := BindQueryParameter("deepObject", true, true, "obj", emptyQuery, &dest)
491+
require.Error(t, err)
492+
assert.Contains(t, err.Error(), "required")
493+
})
494+
495+
t.Run("required/missing with unrelated params returns error", func(t *testing.T) {
496+
var dest SimpleObj
497+
err := BindQueryParameter("deepObject", true, true, "obj", unrelatedQuery, &dest)
498+
require.Error(t, err)
499+
assert.Contains(t, err.Error(), "required")
500+
})
501+
})
502+
437503
t.Run("form", func(t *testing.T) {
438504
expected := &MockBinder{Time: time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC)}
439505
birthday := &MockBinder{}

0 commit comments

Comments
 (0)