-
Notifications
You must be signed in to change notification settings - Fork 0
/
merge_test.go
102 lines (98 loc) · 4.11 KB
/
merge_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
package protoparts
import (
"encoding/hex"
"fmt"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"google.golang.org/protobuf/types/dynamicpb"
)
func TestMerge(t *testing.T) {
tc := [][3]*dynamicpb.Message{
{
// 0: Top-level no-op
testMsg(t, p("Oliver Beattie"), nil, nil, nil, nil, nil),
testMsg(t, nil, nil, nil, nil, nil, nil),
testMsg(t, p("Oliver Beattie"), nil, nil, nil, nil, nil)},
{
// 1: Top-level field replacement
testMsg(t, p("Oliver Beattie"), nil, nil, nil, nil, nil),
testMsg(t, p("Lindy Bishop"), nil, nil, nil, nil, nil),
testMsg(t, p("Lindy Bishop"), nil, nil, nil, nil, nil)},
{
// 2: Top-level field zeroing, with a field that has explicit presence
testMsg(t, p("Oliver Beattie"), nil, nil, nil, nil, nil),
testMsg(t, p(""), nil, nil, nil, nil, nil),
testMsg(t, p(""), nil, nil, nil, nil, nil)},
{
// 3: Nested field replacement
testMsg(t, nil, nil, p("London"), nil, nil, nil),
testMsg(t, nil, nil, p("Los Angeles"), nil, nil, nil),
testMsg(t, nil, nil, p("Los Angeles"), nil, nil, nil)},
{
// 4: Nested no-op
testMsg(t, nil, nil, p("London"), nil, nil, nil),
testMsg(t, nil, nil, nil, nil, nil, nil),
testMsg(t, nil, nil, p("London"), nil, nil, nil)},
{
// 5: List no-op
testMsg(t, nil, nil, nil, []string{"a"}, nil, nil),
testMsg(t, nil, nil, nil, nil, nil, nil),
testMsg(t, nil, nil, nil, []string{"a"}, nil, nil)},
{
// 6: List no-op
testMsg(t, nil, nil, nil, []string{"a"}, nil, nil),
// From the Protobuf docs: "Repeated fields and maps do not track presence: there is no distinction between
// an empty and a not-present repeated field." So, we expect an empty list to the be treated the same as nil
testMsg(t, nil, nil, nil, []string{}, nil, nil),
testMsg(t, nil, nil, nil, []string{"a"}, nil, nil)},
{
// 7: List replacement (second list is longer than the first)
testMsg(t, nil, nil, nil, []string{"a"}, nil, nil),
testMsg(t, nil, nil, nil, []string{"b", "c"}, nil, nil),
testMsg(t, nil, nil, nil, []string{"b", "c"}, nil, nil)},
{
// 8: Partial list replacement (second list is shorter than the first)
testMsg(t, nil, nil, nil, []string{"a", "b", "c"}, nil, nil),
testMsg(t, nil, nil, nil, []string{"aa"}, nil, nil),
testMsg(t, nil, nil, nil, []string{"aa", "b", "c"}, nil, nil)},
{
// 9: Adding a key to a map
testMsg(t, nil, nil, nil, nil, nil, map[string]string{"a": "a", "b": "b"}),
testMsg(t, nil, nil, nil, nil, nil, map[string]string{"c": "c"}),
testMsg(t, nil, nil, nil, nil, nil, map[string]string{"a": "a", "b": "b", "c": "c"})},
{
// 10: Overwriting a key in a map
testMsg(t, nil, nil, nil, nil, nil, map[string]string{"a": "a", "b": "b"}),
testMsg(t, nil, nil, nil, nil, nil, map[string]string{"a": "🤑"}),
testMsg(t, nil, nil, nil, nil, nil, map[string]string{"a": "🤑", "b": "b"})},
{
// 11: Overwriting + adding keys to a map
testMsg(t, nil, nil, nil, nil, nil, map[string]string{"a": "a", "b": "b", "c": "c"}),
testMsg(t, nil, nil, nil, nil, nil, map[string]string{"a": "🤑", "d": "d"}),
testMsg(t, nil, nil, nil, nil, nil, map[string]string{"a": "🤑", "b": "b", "c": "c", "d": "d"})},
}
for i, c := range tc {
t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
before, mutation, expected := c[0], c[1], c[2]
beforeParts, mutationParts := split(t, before), split(t, mutation)
expectedB := marshalProto(t, expected)
afterParts := Merge(beforeParts, mutationParts)
after := afterParts.ProtoMessage()
require.NotNil(t, after)
afterB := marshalProto(t, after.Interface())
if !assert.Equal(t, expectedB, afterB) {
t.Logf(" == %d detail", i)
t.Logf(" Before: %v", beforeParts)
t.Logf(" (bytes):\n%s", hex.Dump((marshalProto(t, before))))
t.Logf("Mutation: %v", mutationParts)
t.Logf(" (bytes):\n%s", hex.Dump(marshalProto(t, mutation)))
t.Logf(" (msg): %v", mutation)
t.Logf("Expected: %v", split(t, expected))
t.Logf(" (bytes):\n%s", hex.Dump(marshalProto(t, expected)))
t.Logf(" Actual: %v", afterParts)
t.Logf(" (bytes):\n%s", hex.Dump(afterB))
}
})
}
}