github.com/dolthub/dolt/go@v0.40.5-0.20240520175717-68db7794bea6/store/prolly/tree/json_diff_test.go (about) 1 // Copyright 2023 Dolthub, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package tree 16 17 import ( 18 "io" 19 "testing" 20 21 "github.com/dolthub/go-mysql-server/sql/types" 22 "github.com/stretchr/testify/assert" 23 "github.com/stretchr/testify/require" 24 ) 25 26 type jsonDiffTest struct { 27 name string 28 from, to types.JsonObject 29 expectedDiffs []JsonDiff 30 } 31 32 var simpleJsonDiffTests = []jsonDiffTest{ 33 { 34 name: "empty object, no modifications", 35 from: types.JsonObject{}, 36 to: types.JsonObject{}, 37 expectedDiffs: nil, 38 }, 39 { 40 name: "insert into empty object", 41 from: types.JsonObject{}, 42 to: types.JsonObject{"a": 1}, 43 expectedDiffs: []JsonDiff{ 44 { 45 Key: "$.\"a\"", 46 From: nil, 47 To: &types.JSONDocument{Val: 1}, 48 Type: AddedDiff, 49 }, 50 }, 51 }, 52 { 53 name: "delete from object", 54 from: types.JsonObject{"a": 1}, 55 to: types.JsonObject{}, 56 expectedDiffs: []JsonDiff{ 57 { 58 Key: "$.\"a\"", 59 From: &types.JSONDocument{Val: 1}, 60 To: nil, 61 Type: RemovedDiff, 62 }, 63 }, 64 }, 65 { 66 name: "modify object", 67 from: types.JsonObject{"a": 1}, 68 to: types.JsonObject{"a": 2}, 69 expectedDiffs: []JsonDiff{ 70 { 71 Key: "$.\"a\"", 72 From: &types.JSONDocument{Val: 1}, 73 To: &types.JSONDocument{Val: 2}, 74 Type: ModifiedDiff, 75 }, 76 }, 77 }, 78 { 79 name: "nested insert", 80 from: types.JsonObject{"a": types.JsonObject{}}, 81 to: types.JsonObject{"a": types.JsonObject{"b": 1}}, 82 expectedDiffs: []JsonDiff{ 83 { 84 Key: "$.\"a\".\"b\"", 85 To: &types.JSONDocument{Val: 1}, 86 Type: AddedDiff, 87 }, 88 }, 89 }, 90 { 91 name: "nested delete", 92 from: types.JsonObject{"a": types.JsonObject{"b": 1}}, 93 to: types.JsonObject{"a": types.JsonObject{}}, 94 expectedDiffs: []JsonDiff{ 95 { 96 Key: "$.\"a\".\"b\"", 97 From: &types.JSONDocument{Val: 1}, 98 Type: RemovedDiff, 99 }, 100 }, 101 }, 102 { 103 name: "nested modify", 104 from: types.JsonObject{"a": types.JsonObject{"b": 1}}, 105 to: types.JsonObject{"a": types.JsonObject{"b": 2}}, 106 expectedDiffs: []JsonDiff{ 107 { 108 Key: "$.\"a\".\"b\"", 109 From: &types.JSONDocument{Val: 1}, 110 To: &types.JSONDocument{Val: 2}, 111 Type: ModifiedDiff, 112 }, 113 }, 114 }, 115 { 116 name: "insert object", 117 from: types.JsonObject{"a": types.JsonObject{}}, 118 to: types.JsonObject{"a": types.JsonObject{"b": types.JsonObject{"c": 3}}}, 119 expectedDiffs: []JsonDiff{ 120 { 121 Key: "$.\"a\".\"b\"", 122 To: &types.JSONDocument{Val: types.JsonObject{"c": 3}}, 123 Type: AddedDiff, 124 }, 125 }, 126 }, 127 { 128 name: "modify to object", 129 from: types.JsonObject{"a": types.JsonObject{"b": 2}}, 130 to: types.JsonObject{"a": types.JsonObject{"b": types.JsonObject{"c": 3}}}, 131 expectedDiffs: []JsonDiff{ 132 { 133 Key: "$.\"a\".\"b\"", 134 From: &types.JSONDocument{Val: 2}, 135 To: &types.JSONDocument{Val: types.JsonObject{"c": 3}}, 136 Type: ModifiedDiff, 137 }, 138 }, 139 }, 140 { 141 name: "modify from object", 142 from: types.JsonObject{"a": types.JsonObject{"b": 2}}, 143 to: types.JsonObject{"a": 1}, 144 expectedDiffs: []JsonDiff{ 145 { 146 Key: "$.\"a\"", 147 From: &types.JSONDocument{Val: types.JsonObject{"b": 2}}, 148 To: &types.JSONDocument{Val: 1}, 149 Type: ModifiedDiff, 150 }, 151 }, 152 }, 153 { 154 name: "remove object", 155 from: types.JsonObject{"a": types.JsonObject{"b": types.JsonObject{"c": 3}}}, 156 to: types.JsonObject{"a": types.JsonObject{}}, 157 expectedDiffs: []JsonDiff{ 158 { 159 Key: "$.\"a\".\"b\"", 160 From: &types.JSONDocument{Val: types.JsonObject{"c": 3}}, 161 Type: RemovedDiff, 162 }, 163 }, 164 }, 165 { 166 name: "insert escaped double quotes", 167 from: types.JsonObject{"\"a\"": "1"}, 168 to: types.JsonObject{"b": "\"2\""}, 169 expectedDiffs: []JsonDiff{ 170 { 171 Key: "$.\"\\\"a\\\"\"", 172 From: &types.JSONDocument{Val: "1"}, 173 To: nil, 174 Type: RemovedDiff, 175 }, 176 { 177 Key: "$.\"b\"", 178 From: nil, 179 To: &types.JSONDocument{Val: "\"2\""}, 180 Type: AddedDiff, 181 }, 182 }, 183 }, 184 { 185 name: "modifications returned in lexographic order", 186 from: types.JsonObject{"a": types.JsonObject{"1": "i"}, "aa": 2, "b": 6}, 187 to: types.JsonObject{"": 1, "a": types.JsonObject{}, "aa": 3, "bb": 5}, 188 expectedDiffs: []JsonDiff{ 189 { 190 Key: "$.\"\"", 191 To: &types.JSONDocument{Val: 1}, 192 Type: AddedDiff, 193 }, 194 { 195 Key: "$.\"a\".\"1\"", 196 From: &types.JSONDocument{Val: "i"}, 197 Type: RemovedDiff, 198 }, 199 { 200 Key: "$.\"aa\"", 201 From: &types.JSONDocument{Val: 2}, 202 To: &types.JSONDocument{Val: 3}, 203 Type: ModifiedDiff, 204 }, 205 { 206 Key: "$.\"b\"", 207 From: &types.JSONDocument{Val: 6}, 208 Type: RemovedDiff, 209 }, 210 { 211 Key: "$.\"bb\"", 212 To: &types.JSONDocument{Val: 5}, 213 Type: AddedDiff, 214 }, 215 }, 216 }, 217 } 218 219 func TestJsonDiff(t *testing.T) { 220 t.Run("simple tests", func(t *testing.T) { 221 runTestBatch(t, simpleJsonDiffTests) 222 }) 223 } 224 225 func runTestBatch(t *testing.T, tests []jsonDiffTest) { 226 for _, test := range tests { 227 t.Run(test.name, func(t *testing.T) { 228 runTest(t, test) 229 }) 230 } 231 } 232 233 func runTest(t *testing.T, test jsonDiffTest) { 234 differ := NewJsonDiffer("$", test.from, test.to) 235 var actualDiffs []JsonDiff 236 for { 237 diff, err := differ.Next() 238 if err == io.EOF { 239 break 240 } 241 assert.NoError(t, err) 242 actualDiffs = append(actualDiffs, diff) 243 } 244 245 require.Equal(t, test.expectedDiffs, actualDiffs) 246 }