From bfcdd34ce17938997ecfe2de88cc97487fdc2d02 Mon Sep 17 00:00:00 2001 From: fly1d <309400591+fly1d@users.noreply.github.com> Date: Fri, 30 Oct 2026 11:14:47 +0800 Subject: [PATCH 1/2] Limit unordered slice diffs to MaxDiff --- deep.go | 3 ++ deep_test.go | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 95 insertions(+) diff --git a/deep.go b/deep.go index 7fb0f7f..faaddb4 100644 --- a/deep.go +++ b/deep.go @@ -517,6 +517,9 @@ func (c *cmp) saveDiff(aval, bval interface{}) { func (c *cmp) cmpMapValueCounts(a, b reflect.Value, am, bm map[interface{}]int, a2b bool) { for v := range am { + if MaxDiff > 0 && len(c.diff) >= MaxDiff { + return + } aCount, _ := am[v] bCount, _ := bm[v] diff --git a/deep_test.go b/deep_test.go index 8ea31ec..642d3af 100644 --- a/deep_test.go +++ b/deep_test.go @@ -1839,3 +1839,95 @@ func TestPointerCycleWithNilPointersAreZero(t *testing.T) { t.Error("nil and nonzero cyclic value must differ") } } + +func TestSliceOrderMaxDiff(t *testing.T) { + originalMaxDiff := deep.MaxDiff + defer func() { deep.MaxDiff = originalMaxDiff }() + + type record struct { + Label string + Values []int + } + for _, test := range []struct { + name string + limit int + a, b interface{} + ordered bool + wantCount int + wantDiff []string + }{ + { + name: "default limit", limit: 10, wantCount: 10, + a: []int{1, 2, 3, 4, 5, 6, 7, 8}, + b: []int{9, 10, 11, 12, 13, 14, 15, 16}, + }, + { + name: "limit one", limit: 1, wantCount: 1, + a: []int{1, 2, 3}, b: []int{4, 5, 6}, + }, + { + name: "left only", limit: 2, wantCount: 2, + a: []int{1, 2, 3, 4}, b: []int{}, + }, + { + name: "right only", limit: 2, wantCount: 2, + a: []int{}, b: []int{1, 2, 3, 4}, + }, + { + name: "reverse pass shares limit", limit: 2, wantCount: 2, + a: []int{1, 1}, b: []int{2, 3}, + }, + { + name: "earlier field shares limit", limit: 2, wantCount: 2, + a: record{"a", []int{1, 2, 3}}, + b: record{"b", []int{4, 5, 6}}, + }, + { + name: "equal reordered duplicates", limit: 1, wantCount: 0, + a: []int{1, 2, 1}, b: []int{2, 1, 1}, + }, + { + name: "below limit multiplicities", limit: 10, wantCount: 3, + a: []int{1, 1}, b: []int{2, 3}, + wantDiff: []string{ + "(unordered) slice[]=1: value count: 2 != 0", + "(unordered) slice[]=2: value count: 0 != 1", + "(unordered) slice[]=3: value count: 0 != 1", + }, + }, + { + name: "ordered control", limit: 2, ordered: true, wantCount: 2, + a: []int{1, 2, 3}, b: []int{4, 5, 6}, + }, + { + name: "zero retains unordered behavior", limit: 0, wantCount: 6, + a: []int{1, 2, 3}, b: []int{4, 5, 6}, + }, + { + name: "negative retains unordered behavior", limit: -1, wantCount: 6, + a: []int{1, 2, 3}, b: []int{4, 5, 6}, + }, + } { + t.Run(test.name, func(t *testing.T) { + deep.MaxDiff = test.limit + var diff []string + if test.ordered { + diff = deep.Equal(test.a, test.b) + } else { + diff = deep.Equal(test.a, test.b, deep.FLAG_IGNORE_SLICE_ORDER) + } + if len(diff) != test.wantCount { + t.Fatalf("got %d diffs, want %d: %v", len(diff), test.wantCount, diff) + } + if test.wantCount == 0 && diff != nil { + t.Fatalf("equal values returned a non-nil diff: %v", diff) + } + if test.wantDiff != nil { + sort.Strings(diff) + if !reflect.DeepEqual(diff, test.wantDiff) { + t.Errorf("got %v, want %v", diff, test.wantDiff) + } + } + }) + } +} From cb58a023a0fd9f314d4255946c18a142ccc6581f Mon Sep 17 00:00:00 2001 From: fly1d <309400591+fly1d@users.noreply.github.com> Date: Sat, 31 Oct 2026 14:16:35 +0800 Subject: [PATCH 2/2] Preserve nonpositive MaxDiff behavior --- deep.go | 2 +- deep_test.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/deep.go b/deep.go index faaddb4..5acad9c 100644 --- a/deep.go +++ b/deep.go @@ -517,7 +517,7 @@ func (c *cmp) saveDiff(aval, bval interface{}) { func (c *cmp) cmpMapValueCounts(a, b reflect.Value, am, bm map[interface{}]int, a2b bool) { for v := range am { - if MaxDiff > 0 && len(c.diff) >= MaxDiff { + if len(c.diff) >= MaxDiff { return } aCount, _ := am[v] diff --git a/deep_test.go b/deep_test.go index 642d3af..c2a29c6 100644 --- a/deep_test.go +++ b/deep_test.go @@ -1900,11 +1900,11 @@ func TestSliceOrderMaxDiff(t *testing.T) { a: []int{1, 2, 3}, b: []int{4, 5, 6}, }, { - name: "zero retains unordered behavior", limit: 0, wantCount: 6, + name: "zero retains unordered behavior", limit: 0, wantCount: 0, a: []int{1, 2, 3}, b: []int{4, 5, 6}, }, { - name: "negative retains unordered behavior", limit: -1, wantCount: 6, + name: "negative retains unordered behavior", limit: -1, wantCount: 0, a: []int{1, 2, 3}, b: []int{4, 5, 6}, }, } {