Skip to content

Commit 0b588ae

Browse files
authored
fix(diff): handle edge case diffing empty against non-empty (#56)
1 parent 506754a commit 0b588ae

File tree

2 files changed

+67
-2
lines changed

2 files changed

+67
-2
lines changed

diff.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,13 @@ func Diff(ctx context.Context, prevBs, curBs cbor.IpldStore, prev, cur cid.Cid,
6767
height: curAmt.height,
6868
}
6969

70+
// edge case of diffing an empty AMT against non-empty
71+
if prevAmt.count == 0 && curAmt.count != 0 {
72+
return addAll(ctx, curCtx, curAmt.node, 0)
73+
}
74+
if prevAmt.count != 0 && curAmt.count == 0 {
75+
return removeAll(ctx, prevCtx, prevAmt.node, 0)
76+
}
7077
return diffNode(ctx, prevCtx, curCtx, prevAmt.node, curAmt.node, 0)
7178
}
7279

diff_test.go

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,8 @@ import (
66
"strconv"
77
"testing"
88

9-
"github.com/stretchr/testify/assert"
10-
119
cbor "github.com/ipfs/go-ipld-cbor"
10+
"github.com/stretchr/testify/assert"
1211
)
1312

1413
type expectedChange struct {
@@ -102,6 +101,65 @@ func TestSimpleAdd(t *testing.T) {
102101
ec.assertExpectation(t, cs[0])
103102
}
104103

104+
func TestDiffEmptyStateWithNonEmptyState(t *testing.T) {
105+
t.Run("Removed values", func(t *testing.T) {
106+
prevBs := cbor.NewCborStore(newMockBlocks())
107+
curBs := cbor.NewCborStore(newMockBlocks())
108+
ctx := context.Background()
109+
110+
prev, err := NewAMT(prevBs)
111+
assert.NoError(t, err)
112+
113+
cur, err := NewAMT(curBs)
114+
assert.NoError(t, err)
115+
assertCount(t, cur, 0)
116+
117+
assertSet(t, prev, 2, "foo")
118+
assertGet(ctx, t, prev, 2, "foo")
119+
assertCount(t, prev, 1)
120+
121+
cs := diffAndAssertLength(ctx, t, prevBs, curBs, prev, cur, 1)
122+
123+
ec := expectedChange{
124+
Type: Remove,
125+
Key: 2,
126+
Before: "foo",
127+
After: "",
128+
}
129+
130+
ec.assertExpectation(t, cs[0])
131+
})
132+
133+
t.Run("Added values", func(t *testing.T) {
134+
prevBs := cbor.NewCborStore(newMockBlocks())
135+
curBs := cbor.NewCborStore(newMockBlocks())
136+
ctx := context.Background()
137+
138+
prev, err := NewAMT(prevBs)
139+
assert.NoError(t, err)
140+
assertCount(t, prev, 0)
141+
142+
cur, err := NewAMT(curBs)
143+
assert.NoError(t, err)
144+
145+
assertSet(t, cur, 2, "foo")
146+
assertGet(ctx, t, cur, 2, "foo")
147+
assertCount(t, cur, 1)
148+
149+
cs := diffAndAssertLength(ctx, t, prevBs, curBs, prev, cur, 1)
150+
151+
ec := expectedChange{
152+
Type: Add,
153+
Key: 2,
154+
Before: "",
155+
After: "foo",
156+
}
157+
158+
ec.assertExpectation(t, cs[0])
159+
160+
})
161+
}
162+
105163
func TestSimpleRemove(t *testing.T) {
106164
prevBs := cbor.NewCborStore(newMockBlocks())
107165
curBs := cbor.NewCborStore(newMockBlocks())

0 commit comments

Comments
 (0)