github.com/spotmaxtech/k8s-apimachinery-v0260@v0.0.1/pkg/util/strategicpatch/patch_test.go (about) 1 /* 2 Copyright 2014 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package strategicpatch 18 19 import ( 20 "fmt" 21 "path/filepath" 22 "reflect" 23 "strings" 24 "testing" 25 26 "github.com/davecgh/go-spew/spew" 27 "sigs.k8s.io/yaml" 28 29 "github.com/spotmaxtech/k8s-apimachinery-v0260/pkg/runtime" 30 "github.com/spotmaxtech/k8s-apimachinery-v0260/pkg/util/json" 31 "github.com/spotmaxtech/k8s-apimachinery-v0260/pkg/util/mergepatch" 32 "github.com/spotmaxtech/k8s-apimachinery-v0260/pkg/util/sets" 33 sptest "github.com/spotmaxtech/k8s-apimachinery-v0260/pkg/util/strategicpatch/testing" 34 ) 35 36 var ( 37 fakeMergeItemSchema = sptest.Fake{Path: filepath.Join("testdata", "swagger-merge-item.json")} 38 fakePrecisionItemSchema = sptest.Fake{Path: filepath.Join("testdata", "swagger-precision-item.json")} 39 ) 40 41 type SortMergeListTestCases struct { 42 TestCases []SortMergeListTestCase 43 } 44 45 type SortMergeListTestCase struct { 46 Description string 47 Original map[string]interface{} 48 Sorted map[string]interface{} 49 } 50 51 type StrategicMergePatchTestCases struct { 52 TestCases []StrategicMergePatchTestCase 53 } 54 55 type StrategicMergePatchTestCase struct { 56 Description string 57 StrategicMergePatchTestCaseData 58 } 59 60 type StrategicMergePatchRawTestCase struct { 61 Description string 62 StrategicMergePatchRawTestCaseData 63 } 64 65 type StrategicMergePatchTestCaseData struct { 66 // Original is the original object (last-applied config in annotation) 67 Original map[string]interface{} 68 // Modified is the modified object (new config we want) 69 Modified map[string]interface{} 70 // Current is the current object (live config in the server) 71 Current map[string]interface{} 72 // TwoWay is the expected two-way merge patch diff between original and modified 73 TwoWay map[string]interface{} 74 // ThreeWay is the expected three-way merge patch 75 ThreeWay map[string]interface{} 76 // Result is the expected object after applying the three-way patch on current object. 77 Result map[string]interface{} 78 // TwoWayResult is the expected object after applying the two-way patch on current object. 79 // If nil, Modified is used. 80 TwoWayResult map[string]interface{} 81 } 82 83 // The meaning of each field is the same as StrategicMergePatchTestCaseData's. 84 // The difference is that all the fields in StrategicMergePatchRawTestCaseData are json-encoded data. 85 type StrategicMergePatchRawTestCaseData struct { 86 Original []byte 87 Modified []byte 88 Current []byte 89 TwoWay []byte 90 ThreeWay []byte 91 Result []byte 92 TwoWayResult []byte 93 ExpectedError string 94 } 95 96 type MergeItem struct { 97 Name string `json:"name,omitempty"` 98 Value string `json:"value,omitempty"` 99 Other string `json:"other,omitempty"` 100 MergingList []MergeItem `json:"mergingList,omitempty" patchStrategy:"merge" patchMergeKey:"name"` 101 NonMergingList []MergeItem `json:"nonMergingList,omitempty"` 102 MergingIntList []int `json:"mergingIntList,omitempty" patchStrategy:"merge"` 103 NonMergingIntList []int `json:"nonMergingIntList,omitempty"` 104 MergeItemPtr *MergeItem `json:"mergeItemPtr,omitempty" patchStrategy:"merge" patchMergeKey:"name"` 105 SimpleMap map[string]string `json:"simpleMap,omitempty"` 106 ReplacingItem runtime.RawExtension `json:"replacingItem,omitempty" patchStrategy:"replace"` 107 RetainKeysMap RetainKeysMergeItem `json:"retainKeysMap,omitempty" patchStrategy:"retainKeys"` 108 RetainKeysMergingList []MergeItem `json:"retainKeysMergingList,omitempty" patchStrategy:"merge,retainKeys" patchMergeKey:"name"` 109 } 110 111 type RetainKeysMergeItem struct { 112 Name string `json:"name,omitempty"` 113 Value string `json:"value,omitempty"` 114 Other string `json:"other,omitempty"` 115 SimpleMap map[string]string `json:"simpleMap,omitempty"` 116 MergingIntList []int `json:"mergingIntList,omitempty" patchStrategy:"merge"` 117 MergingList []MergeItem `json:"mergingList,omitempty" patchStrategy:"merge" patchMergeKey:"name"` 118 NonMergingList []MergeItem `json:"nonMergingList,omitempty"` 119 } 120 121 var ( 122 mergeItem MergeItem 123 mergeItemStructSchema = PatchMetaFromStruct{T: GetTagStructTypeOrDie(mergeItem)} 124 ) 125 126 // These are test cases for SortMergeList, used to assert that it (recursively) 127 // sorts both merging and non merging lists correctly. 128 var sortMergeListTestCaseData = []byte(` 129 testCases: 130 - description: sort one list of maps 131 original: 132 mergingList: 133 - name: 1 134 - name: 3 135 - name: 2 136 sorted: 137 mergingList: 138 - name: 1 139 - name: 2 140 - name: 3 141 - description: sort lists of maps but not nested lists of maps 142 original: 143 mergingList: 144 - name: 2 145 nonMergingList: 146 - name: 1 147 - name: 3 148 - name: 2 149 - name: 1 150 nonMergingList: 151 - name: 2 152 - name: 1 153 sorted: 154 mergingList: 155 - name: 1 156 nonMergingList: 157 - name: 2 158 - name: 1 159 - name: 2 160 nonMergingList: 161 - name: 1 162 - name: 3 163 - name: 2 164 - description: sort lists of maps and nested lists of maps 165 original: 166 mergingList: 167 - name: 2 168 mergingList: 169 - name: 1 170 - name: 3 171 - name: 2 172 - name: 1 173 mergingList: 174 - name: 2 175 - name: 1 176 sorted: 177 mergingList: 178 - name: 1 179 mergingList: 180 - name: 1 181 - name: 2 182 - name: 2 183 mergingList: 184 - name: 1 185 - name: 2 186 - name: 3 187 - description: merging list should NOT sort when nested in non merging list 188 original: 189 nonMergingList: 190 - name: 2 191 mergingList: 192 - name: 1 193 - name: 3 194 - name: 2 195 - name: 1 196 mergingList: 197 - name: 2 198 - name: 1 199 sorted: 200 nonMergingList: 201 - name: 2 202 mergingList: 203 - name: 1 204 - name: 3 205 - name: 2 206 - name: 1 207 mergingList: 208 - name: 2 209 - name: 1 210 - description: sort very nested list of maps 211 fieldTypes: 212 original: 213 mergingList: 214 - mergingList: 215 - mergingList: 216 - name: 2 217 - name: 1 218 sorted: 219 mergingList: 220 - mergingList: 221 - mergingList: 222 - name: 1 223 - name: 2 224 - description: sort nested lists of ints 225 original: 226 mergingList: 227 - name: 2 228 mergingIntList: 229 - 1 230 - 3 231 - 2 232 - name: 1 233 mergingIntList: 234 - 2 235 - 1 236 sorted: 237 mergingList: 238 - name: 1 239 mergingIntList: 240 - 1 241 - 2 242 - name: 2 243 mergingIntList: 244 - 1 245 - 2 246 - 3 247 - description: sort nested pointers of ints 248 original: 249 mergeItemPtr: 250 - name: 2 251 mergingIntList: 252 - 1 253 - 3 254 - 2 255 - name: 1 256 mergingIntList: 257 - 2 258 - 1 259 sorted: 260 mergeItemPtr: 261 - name: 1 262 mergingIntList: 263 - 1 264 - 2 265 - name: 2 266 mergingIntList: 267 - 1 268 - 2 269 - 3 270 - description: sort merging list by pointer 271 original: 272 mergeItemPtr: 273 - name: 1 274 - name: 3 275 - name: 2 276 sorted: 277 mergeItemPtr: 278 - name: 1 279 - name: 2 280 - name: 3 281 `) 282 283 func TestSortMergeLists(t *testing.T) { 284 mergeItemOpenapiSchema := PatchMetaFromOpenAPI{ 285 Schema: sptest.GetSchemaOrDie(&fakeMergeItemSchema, "mergeItem"), 286 } 287 schemas := []LookupPatchMeta{ 288 mergeItemStructSchema, 289 mergeItemOpenapiSchema, 290 } 291 292 tc := SortMergeListTestCases{} 293 err := yaml.Unmarshal(sortMergeListTestCaseData, &tc) 294 if err != nil { 295 t.Errorf("can't unmarshal test cases: %s\n", err) 296 return 297 } 298 299 for _, schema := range schemas { 300 for _, c := range tc.TestCases { 301 temp := testObjectToJSONOrFail(t, c.Original) 302 got := sortJsonOrFail(t, temp, c.Description, schema) 303 expected := testObjectToJSONOrFail(t, c.Sorted) 304 if !reflect.DeepEqual(got, expected) { 305 t.Errorf("using %s error in test case: %s\ncannot sort object:\n%s\nexpected:\n%s\ngot:\n%s\n", 306 getSchemaType(schema), c.Description, mergepatch.ToYAMLOrError(c.Original), mergepatch.ToYAMLOrError(c.Sorted), jsonToYAMLOrError(got)) 307 } 308 } 309 } 310 } 311 312 // These are test cases for StrategicMergePatch that cannot be generated using 313 // CreateTwoWayMergePatch because it may be one of the following cases: 314 // - not use the replace directive. 315 // - generate duplicate integers for a merging list patch. 316 // - generate empty merging lists. 317 // - use patch format from an old client. 318 var customStrategicMergePatchTestCaseData = []byte(` 319 testCases: 320 - description: unique scalars when merging lists 321 original: 322 mergingIntList: 323 - 1 324 - 2 325 twoWay: 326 mergingIntList: 327 - 2 328 - 3 329 modified: 330 mergingIntList: 331 - 1 332 - 2 333 - 3 334 - description: delete map from nested map 335 original: 336 simpleMap: 337 key1: 1 338 key2: 1 339 twoWay: 340 simpleMap: 341 $patch: delete 342 modified: 343 simpleMap: 344 {} 345 - description: delete all items from merging list 346 original: 347 mergingList: 348 - name: 1 349 - name: 2 350 twoWay: 351 mergingList: 352 - $patch: replace 353 modified: 354 mergingList: [] 355 - description: merge empty merging lists 356 original: 357 mergingList: [] 358 twoWay: 359 mergingList: [] 360 modified: 361 mergingList: [] 362 - description: delete all keys from map 363 original: 364 name: 1 365 value: 1 366 twoWay: 367 $patch: replace 368 modified: {} 369 - description: add key and delete all keys from map 370 original: 371 name: 1 372 value: 1 373 twoWay: 374 other: a 375 $patch: replace 376 modified: 377 other: a 378 - description: delete all duplicate entries in a merging list 379 original: 380 mergingList: 381 - name: 1 382 - name: 1 383 - name: 2 384 value: a 385 - name: 3 386 - name: 3 387 twoWay: 388 mergingList: 389 - name: 1 390 $patch: delete 391 - name: 3 392 $patch: delete 393 modified: 394 mergingList: 395 - name: 2 396 value: a 397 - description: retainKeys map can add a field when no retainKeys directive present 398 original: 399 retainKeysMap: 400 name: foo 401 twoWay: 402 retainKeysMap: 403 value: bar 404 modified: 405 retainKeysMap: 406 name: foo 407 value: bar 408 - description: retainKeys map can change a field when no retainKeys directive present 409 original: 410 retainKeysMap: 411 name: foo 412 value: a 413 twoWay: 414 retainKeysMap: 415 value: b 416 modified: 417 retainKeysMap: 418 name: foo 419 value: b 420 - description: retainKeys map can delete a field when no retainKeys directive present 421 original: 422 retainKeysMap: 423 name: foo 424 value: a 425 twoWay: 426 retainKeysMap: 427 value: null 428 modified: 429 retainKeysMap: 430 name: foo 431 - description: retainKeys map merge an empty map 432 original: 433 retainKeysMap: 434 name: foo 435 value: a 436 twoWay: 437 retainKeysMap: {} 438 modified: 439 retainKeysMap: 440 name: foo 441 value: a 442 - description: retainKeys list can add a field when no retainKeys directive present 443 original: 444 retainKeysMergingList: 445 - name: bar 446 - name: foo 447 twoWay: 448 retainKeysMergingList: 449 - name: foo 450 value: a 451 modified: 452 retainKeysMergingList: 453 - name: bar 454 - name: foo 455 value: a 456 - description: retainKeys list can change a field when no retainKeys directive present 457 original: 458 retainKeysMergingList: 459 - name: bar 460 - name: foo 461 value: a 462 twoWay: 463 retainKeysMergingList: 464 - name: foo 465 value: b 466 modified: 467 retainKeysMergingList: 468 - name: bar 469 - name: foo 470 value: b 471 - description: retainKeys list can delete a field when no retainKeys directive present 472 original: 473 retainKeysMergingList: 474 - name: bar 475 - name: foo 476 value: a 477 twoWay: 478 retainKeysMergingList: 479 - name: foo 480 value: null 481 modified: 482 retainKeysMergingList: 483 - name: bar 484 - name: foo 485 - description: preserve the order from the patch in a merging list 486 original: 487 mergingList: 488 - name: 1 489 - name: 2 490 value: b 491 - name: 3 492 twoWay: 493 mergingList: 494 - name: 3 495 value: c 496 - name: 1 497 value: a 498 - name: 2 499 other: x 500 modified: 501 mergingList: 502 - name: 3 503 value: c 504 - name: 1 505 value: a 506 - name: 2 507 value: b 508 other: x 509 - description: preserve the order from the patch in a merging list 2 510 original: 511 mergingList: 512 - name: 1 513 - name: 2 514 value: b 515 - name: 3 516 twoWay: 517 mergingList: 518 - name: 3 519 value: c 520 - name: 1 521 value: a 522 modified: 523 mergingList: 524 - name: 2 525 value: b 526 - name: 3 527 value: c 528 - name: 1 529 value: a 530 - description: preserve the order from the patch in a merging int list 531 original: 532 mergingIntList: 533 - 1 534 - 2 535 - 3 536 twoWay: 537 mergingIntList: 538 - 3 539 - 1 540 - 2 541 modified: 542 mergingIntList: 543 - 3 544 - 1 545 - 2 546 - description: preserve the order from the patch in a merging int list 547 original: 548 mergingIntList: 549 - 1 550 - 2 551 - 3 552 twoWay: 553 mergingIntList: 554 - 3 555 - 1 556 modified: 557 mergingIntList: 558 - 2 559 - 3 560 - 1 561 `) 562 563 var customStrategicMergePatchRawTestCases = []StrategicMergePatchRawTestCase{ 564 { 565 Description: "$setElementOrder contains item that is not present in the list to be merged", 566 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 567 Original: []byte(` 568 mergingList: 569 - name: 1 570 - name: 3 571 `), 572 TwoWay: []byte(` 573 $setElementOrder/mergingList: 574 - name: 3 575 - name: 2 576 - name: 1 577 mergingList: 578 - name: 3 579 value: 3 580 - name: 1 581 value: 1 582 `), 583 Modified: []byte(` 584 mergingList: 585 - name: 3 586 value: 3 587 - name: 1 588 value: 1 589 `), 590 }, 591 }, 592 { 593 Description: "$setElementOrder contains item that is not present in the int list to be merged", 594 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 595 Original: []byte(` 596 mergingIntList: 597 - 1 598 - 3 599 `), 600 TwoWay: []byte(` 601 $setElementOrder/mergingIntList: 602 - 3 603 - 2 604 - 1 605 `), 606 Modified: []byte(` 607 mergingIntList: 608 - 3 609 - 1 610 `), 611 }, 612 }, 613 { 614 Description: "should check if order in $setElementOrder and patch list match", 615 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 616 Original: []byte(` 617 mergingList: 618 - name: 1 619 - name: 3 620 - name: 2 621 `), 622 TwoWay: []byte(` 623 $setElementOrder/mergingList: 624 - name: 1 625 - name: 2 626 - name: 3 627 mergingList: 628 - name: 3 629 value: 3 630 - name: 1 631 value: 1 632 `), 633 ExpectedError: "doesn't match", 634 }, 635 }, 636 { 637 Description: "$setElementOrder contains item that is not present in the int list to be merged", 638 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 639 Original: []byte(` 640 mergingIntList: 641 - 1 642 - 3 643 - 2 644 `), 645 TwoWay: []byte(` 646 $setElementOrder/mergingIntList: 647 - 1 648 - 2 649 - 3 650 mergingIntList: 651 - 3 652 - 1 653 `), 654 ExpectedError: "doesn't match", 655 }, 656 }, 657 { 658 Description: "missing merge key should error out", 659 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 660 Original: []byte(` 661 mergingList: 662 - name: 1 663 value: a 664 `), 665 TwoWay: []byte(` 666 mergingList: 667 - value: b 668 `), 669 ExpectedError: "does not contain declared merge key", 670 }, 671 }, 672 { 673 Description: "$deleteFromPrimitiveList of nonexistent item in primitive list should not add the item to the list", 674 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 675 Original: []byte(` 676 mergingIntList: 677 - 1 678 - 2 679 `), 680 TwoWay: []byte(` 681 $deleteFromPrimitiveList/mergingIntList: 682 - 3 683 `), 684 Modified: []byte(` 685 mergingIntList: 686 - 1 687 - 2 688 `), 689 }, 690 }, 691 { 692 Description: "$deleteFromPrimitiveList on empty primitive list should not add the item to the list", 693 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 694 Original: []byte(` 695 mergingIntList: 696 `), 697 TwoWay: []byte(` 698 $deleteFromPrimitiveList/mergingIntList: 699 - 3 700 `), 701 Modified: []byte(` 702 mergingIntList: 703 `), 704 }, 705 }, 706 { 707 Description: "$deleteFromPrimitiveList on nonexistent primitive list should not add the primitive list", 708 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 709 Original: []byte(` 710 foo: 711 - bar 712 `), 713 TwoWay: []byte(` 714 $deleteFromPrimitiveList/mergingIntList: 715 - 3 716 `), 717 Modified: []byte(` 718 foo: 719 - bar 720 `), 721 }, 722 }, 723 } 724 725 func TestCustomStrategicMergePatch(t *testing.T) { 726 mergeItemOpenapiSchema := PatchMetaFromOpenAPI{ 727 Schema: sptest.GetSchemaOrDie(&fakeMergeItemSchema, "mergeItem"), 728 } 729 schemas := []LookupPatchMeta{ 730 mergeItemStructSchema, 731 mergeItemOpenapiSchema, 732 } 733 734 tc := StrategicMergePatchTestCases{} 735 err := yaml.Unmarshal(customStrategicMergePatchTestCaseData, &tc) 736 if err != nil { 737 t.Errorf("can't unmarshal test cases: %v\n", err) 738 return 739 } 740 741 for _, schema := range schemas { 742 for _, c := range tc.TestCases { 743 original, expectedTwoWayPatch, _, expectedResult := twoWayTestCaseToJSONOrFail(t, c, schema) 744 testPatchApplication(t, original, expectedTwoWayPatch, expectedResult, c.Description, "", schema) 745 } 746 747 for _, c := range customStrategicMergePatchRawTestCases { 748 original, expectedTwoWayPatch, _, expectedResult := twoWayRawTestCaseToJSONOrFail(t, c) 749 testPatchApplication(t, original, expectedTwoWayPatch, expectedResult, c.Description, c.ExpectedError, schema) 750 } 751 } 752 } 753 754 // These are test cases for StrategicMergePatch, to assert that applying a patch 755 // yields the correct outcome. They are also test cases for CreateTwoWayMergePatch 756 // and CreateThreeWayMergePatch, to assert that they both generate the correct patch 757 // for the given set of input documents. 758 var createStrategicMergePatchTestCaseData = []byte(` 759 testCases: 760 - description: nil original 761 twoWay: 762 name: 1 763 value: 1 764 modified: 765 name: 1 766 value: 1 767 current: 768 name: 1 769 other: a 770 threeWay: 771 value: 1 772 result: 773 name: 1 774 value: 1 775 other: a 776 - description: nil patch 777 original: 778 name: 1 779 twoWay: 780 {} 781 modified: 782 name: 1 783 current: 784 name: 1 785 threeWay: 786 {} 787 result: 788 name: 1 789 - description: add field to map 790 original: 791 name: 1 792 twoWay: 793 value: 1 794 modified: 795 name: 1 796 value: 1 797 current: 798 name: 1 799 other: a 800 threeWay: 801 value: 1 802 result: 803 name: 1 804 value: 1 805 other: a 806 - description: add field to map with conflict 807 original: 808 name: 1 809 twoWay: 810 value: 1 811 modified: 812 name: 1 813 value: 1 814 current: 815 name: a 816 other: a 817 threeWay: 818 name: 1 819 value: 1 820 result: 821 name: 1 822 value: 1 823 other: a 824 - description: add field and delete field from map 825 original: 826 name: 1 827 twoWay: 828 name: null 829 value: 1 830 modified: 831 value: 1 832 current: 833 name: 1 834 other: a 835 threeWay: 836 name: null 837 value: 1 838 result: 839 value: 1 840 other: a 841 - description: add field and delete field from map with conflict 842 original: 843 name: 1 844 twoWay: 845 name: null 846 value: 1 847 modified: 848 value: 1 849 current: 850 name: a 851 other: a 852 threeWay: 853 name: null 854 value: 1 855 result: 856 value: 1 857 other: a 858 - description: delete field from nested map 859 original: 860 simpleMap: 861 key1: 1 862 key2: 1 863 twoWay: 864 simpleMap: 865 key2: null 866 modified: 867 simpleMap: 868 key1: 1 869 current: 870 simpleMap: 871 key1: 1 872 key2: 1 873 other: a 874 threeWay: 875 simpleMap: 876 key2: null 877 result: 878 simpleMap: 879 key1: 1 880 other: a 881 - description: delete field from nested map with conflict 882 original: 883 simpleMap: 884 key1: 1 885 key2: 1 886 twoWay: 887 simpleMap: 888 key2: null 889 modified: 890 simpleMap: 891 key1: 1 892 current: 893 simpleMap: 894 key1: a 895 key2: 1 896 other: a 897 threeWay: 898 simpleMap: 899 key1: 1 900 key2: null 901 result: 902 simpleMap: 903 key1: 1 904 other: a 905 - description: delete all fields from map 906 original: 907 name: 1 908 value: 1 909 twoWay: 910 name: null 911 value: null 912 modified: {} 913 current: 914 name: 1 915 value: 1 916 other: a 917 threeWay: 918 name: null 919 value: null 920 result: 921 other: a 922 - description: delete all fields from map with conflict 923 original: 924 name: 1 925 value: 1 926 twoWay: 927 name: null 928 value: null 929 modified: {} 930 current: 931 name: 1 932 value: a 933 other: a 934 threeWay: 935 name: null 936 value: null 937 result: 938 other: a 939 - description: add field and delete all fields from map 940 original: 941 name: 1 942 value: 1 943 twoWay: 944 name: null 945 value: null 946 other: a 947 modified: 948 other: a 949 current: 950 name: 1 951 value: 1 952 other: a 953 threeWay: 954 name: null 955 value: null 956 result: 957 other: a 958 - description: add field and delete all fields from map with conflict 959 original: 960 name: 1 961 value: 1 962 twoWay: 963 name: null 964 value: null 965 other: a 966 modified: 967 other: a 968 current: 969 name: 1 970 value: 1 971 other: b 972 threeWay: 973 name: null 974 value: null 975 other: a 976 result: 977 other: a 978 - description: replace list of scalars 979 original: 980 nonMergingIntList: 981 - 1 982 - 2 983 twoWay: 984 nonMergingIntList: 985 - 2 986 - 3 987 modified: 988 nonMergingIntList: 989 - 2 990 - 3 991 current: 992 nonMergingIntList: 993 - 1 994 - 2 995 threeWay: 996 nonMergingIntList: 997 - 2 998 - 3 999 result: 1000 nonMergingIntList: 1001 - 2 1002 - 3 1003 - description: replace list of scalars with conflict 1004 original: 1005 nonMergingIntList: 1006 - 1 1007 - 2 1008 twoWay: 1009 nonMergingIntList: 1010 - 2 1011 - 3 1012 modified: 1013 nonMergingIntList: 1014 - 2 1015 - 3 1016 current: 1017 nonMergingIntList: 1018 - 1 1019 - 4 1020 threeWay: 1021 nonMergingIntList: 1022 - 2 1023 - 3 1024 result: 1025 nonMergingIntList: 1026 - 2 1027 - 3 1028 - description: delete all maps from merging list 1029 original: 1030 mergingList: 1031 - name: 1 1032 - name: 2 1033 twoWay: 1034 mergingList: 1035 - name: 1 1036 $patch: delete 1037 - name: 2 1038 $patch: delete 1039 modified: 1040 mergingList: [] 1041 current: 1042 mergingList: 1043 - name: 1 1044 - name: 2 1045 threeWay: 1046 mergingList: 1047 - name: 1 1048 $patch: delete 1049 - name: 2 1050 $patch: delete 1051 result: 1052 mergingList: [] 1053 - description: delete all maps from merging list with conflict 1054 original: 1055 mergingList: 1056 - name: 1 1057 - name: 2 1058 twoWay: 1059 mergingList: 1060 - name: 1 1061 $patch: delete 1062 - name: 2 1063 $patch: delete 1064 modified: 1065 mergingList: [] 1066 current: 1067 mergingList: 1068 - name: 1 1069 other: a 1070 - name: 2 1071 other: b 1072 threeWay: 1073 mergingList: 1074 - name: 1 1075 $patch: delete 1076 - name: 2 1077 $patch: delete 1078 result: 1079 mergingList: [] 1080 - description: delete all maps from empty merging list 1081 original: 1082 mergingList: 1083 - name: 1 1084 - name: 2 1085 twoWay: 1086 mergingList: 1087 - name: 1 1088 $patch: delete 1089 - name: 2 1090 $patch: delete 1091 modified: 1092 mergingList: [] 1093 current: 1094 mergingList: [] 1095 threeWay: 1096 mergingList: 1097 - name: 1 1098 $patch: delete 1099 - name: 2 1100 $patch: delete 1101 result: 1102 mergingList: [] 1103 - description: merge empty merging lists 1104 original: 1105 mergingList: [] 1106 twoWay: 1107 {} 1108 modified: 1109 mergingList: [] 1110 current: 1111 mergingList: [] 1112 threeWay: 1113 {} 1114 result: 1115 mergingList: [] 1116 - description: defined null values should propagate overwrite current fields (with conflict) 1117 original: 1118 name: 2 1119 twoWay: 1120 name: 1 1121 value: 1 1122 other: null 1123 twoWayResult: 1124 name: 1 1125 value: 1 1126 modified: 1127 name: 1 1128 value: 1 1129 other: null 1130 current: 1131 name: a 1132 other: a 1133 threeWay: 1134 name: 1 1135 value: 1 1136 other: null 1137 result: 1138 name: 1 1139 value: 1 1140 - description: defined null values should propagate removing original fields 1141 original: 1142 name: original-name 1143 value: original-value 1144 current: 1145 name: original-name 1146 value: original-value 1147 other: current-other 1148 modified: 1149 name: modified-name 1150 value: null 1151 twoWay: 1152 name: modified-name 1153 value: null 1154 twoWayResult: 1155 name: modified-name 1156 threeWay: 1157 name: modified-name 1158 value: null 1159 result: 1160 name: modified-name 1161 other: current-other 1162 - description: nil patch with retainKeys map 1163 original: 1164 name: a 1165 retainKeysMap: 1166 name: foo 1167 current: 1168 name: a 1169 value: b 1170 retainKeysMap: 1171 name: foo 1172 modified: 1173 name: a 1174 retainKeysMap: 1175 name: foo 1176 twoWay: {} 1177 threeWay: {} 1178 result: 1179 name: a 1180 value: b 1181 retainKeysMap: 1182 name: foo 1183 - description: retainKeys map with no change should not be present 1184 original: 1185 name: a 1186 retainKeysMap: 1187 name: foo 1188 current: 1189 name: a 1190 other: c 1191 retainKeysMap: 1192 name: foo 1193 modified: 1194 name: a 1195 value: b 1196 retainKeysMap: 1197 name: foo 1198 twoWay: 1199 value: b 1200 threeWay: 1201 value: b 1202 result: 1203 name: a 1204 value: b 1205 other: c 1206 retainKeysMap: 1207 name: foo 1208 `) 1209 1210 var strategicMergePatchRawTestCases = []StrategicMergePatchRawTestCase{ 1211 { 1212 Description: "delete items in lists of scalars", 1213 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 1214 Original: []byte(` 1215 mergingIntList: 1216 - 1 1217 - 2 1218 - 3 1219 `), 1220 TwoWay: []byte(` 1221 $setElementOrder/mergingIntList: 1222 - 1 1223 - 2 1224 $deleteFromPrimitiveList/mergingIntList: 1225 - 3 1226 `), 1227 Modified: []byte(` 1228 mergingIntList: 1229 - 1 1230 - 2 1231 `), 1232 Current: []byte(` 1233 mergingIntList: 1234 - 1 1235 - 2 1236 - 3 1237 - 4 1238 `), 1239 ThreeWay: []byte(` 1240 $setElementOrder/mergingIntList: 1241 - 1 1242 - 2 1243 $deleteFromPrimitiveList/mergingIntList: 1244 - 3 1245 `), 1246 Result: []byte(` 1247 mergingIntList: 1248 - 1 1249 - 2 1250 - 4 1251 `), 1252 }, 1253 }, 1254 { 1255 Description: "delete all duplicate items in lists of scalars", 1256 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 1257 Original: []byte(` 1258 mergingIntList: 1259 - 1 1260 - 2 1261 - 3 1262 - 3 1263 `), 1264 TwoWay: []byte(` 1265 $setElementOrder/mergingIntList: 1266 - 1 1267 - 2 1268 $deleteFromPrimitiveList/mergingIntList: 1269 - 3 1270 `), 1271 Modified: []byte(` 1272 mergingIntList: 1273 - 1 1274 - 2 1275 `), 1276 Current: []byte(` 1277 mergingIntList: 1278 - 1 1279 - 2 1280 - 3 1281 - 3 1282 - 4 1283 `), 1284 ThreeWay: []byte(` 1285 $setElementOrder/mergingIntList: 1286 - 1 1287 - 2 1288 $deleteFromPrimitiveList/mergingIntList: 1289 - 3 1290 `), 1291 Result: []byte(` 1292 mergingIntList: 1293 - 1 1294 - 2 1295 - 4 1296 `), 1297 }, 1298 }, 1299 { 1300 Description: "add and delete items in lists of scalars", 1301 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 1302 Original: []byte(` 1303 mergingIntList: 1304 - 1 1305 - 2 1306 - 3 1307 `), 1308 TwoWay: []byte(` 1309 $setElementOrder/mergingIntList: 1310 - 1 1311 - 2 1312 - 4 1313 $deleteFromPrimitiveList/mergingIntList: 1314 - 3 1315 mergingIntList: 1316 - 4 1317 `), 1318 Modified: []byte(` 1319 mergingIntList: 1320 - 1 1321 - 2 1322 - 4 1323 `), 1324 Current: []byte(` 1325 mergingIntList: 1326 - 1 1327 - 2 1328 - 3 1329 - 4 1330 `), 1331 ThreeWay: []byte(` 1332 $setElementOrder/mergingIntList: 1333 - 1 1334 - 2 1335 - 4 1336 $deleteFromPrimitiveList/mergingIntList: 1337 - 3 1338 `), 1339 Result: []byte(` 1340 mergingIntList: 1341 - 1 1342 - 2 1343 - 4 1344 `), 1345 }, 1346 }, 1347 { 1348 Description: "merge lists of maps", 1349 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 1350 Original: []byte(` 1351 mergingList: 1352 - name: 1 1353 - name: 2 1354 value: 2 1355 `), 1356 TwoWay: []byte(` 1357 $setElementOrder/mergingList: 1358 - name: 4 1359 - name: 1 1360 - name: 2 1361 - name: 3 1362 mergingList: 1363 - name: 4 1364 value: 4 1365 - name: 3 1366 value: 3 1367 `), 1368 Modified: []byte(` 1369 mergingList: 1370 - name: 4 1371 value: 4 1372 - name: 1 1373 - name: 2 1374 value: 2 1375 - name: 3 1376 value: 3 1377 `), 1378 Current: []byte(` 1379 mergingList: 1380 - name: 1 1381 other: a 1382 - name: 2 1383 value: 2 1384 other: b 1385 `), 1386 ThreeWay: []byte(` 1387 $setElementOrder/mergingList: 1388 - name: 4 1389 - name: 1 1390 - name: 2 1391 - name: 3 1392 mergingList: 1393 - name: 4 1394 value: 4 1395 - name: 3 1396 value: 3 1397 `), 1398 Result: []byte(` 1399 mergingList: 1400 - name: 4 1401 value: 4 1402 - name: 1 1403 other: a 1404 - name: 2 1405 value: 2 1406 other: b 1407 - name: 3 1408 value: 3 1409 `), 1410 }, 1411 }, 1412 { 1413 Description: "merge lists of maps with conflict", 1414 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 1415 Original: []byte(` 1416 mergingList: 1417 - name: 1 1418 - name: 2 1419 value: 2 1420 `), 1421 TwoWay: []byte(` 1422 $setElementOrder/mergingList: 1423 - name: 1 1424 - name: 2 1425 - name: 3 1426 mergingList: 1427 - name: 3 1428 value: 3 1429 `), 1430 Modified: []byte(` 1431 mergingList: 1432 - name: 1 1433 - name: 2 1434 value: 2 1435 - name: 3 1436 value: 3 1437 `), 1438 Current: []byte(` 1439 mergingList: 1440 - name: 1 1441 other: a 1442 - name: 2 1443 value: 3 1444 other: b 1445 `), 1446 ThreeWay: []byte(` 1447 $setElementOrder/mergingList: 1448 - name: 1 1449 - name: 2 1450 - name: 3 1451 mergingList: 1452 - name: 2 1453 value: 2 1454 - name: 3 1455 value: 3 1456 `), 1457 Result: []byte(` 1458 mergingList: 1459 - name: 1 1460 other: a 1461 - name: 2 1462 value: 2 1463 other: b 1464 - name: 3 1465 value: 3 1466 `), 1467 }, 1468 }, 1469 { 1470 Description: "add field to map in merging list", 1471 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 1472 Original: []byte(` 1473 mergingList: 1474 - name: 1 1475 - name: 2 1476 value: 2 1477 `), 1478 TwoWay: []byte(` 1479 $setElementOrder/mergingList: 1480 - name: 1 1481 - name: 2 1482 mergingList: 1483 - name: 1 1484 value: 1 1485 `), 1486 Modified: []byte(` 1487 mergingList: 1488 - name: 1 1489 value: 1 1490 - name: 2 1491 value: 2 1492 `), 1493 Current: []byte(` 1494 mergingList: 1495 - name: 1 1496 other: a 1497 - name: 2 1498 value: 2 1499 other: b 1500 `), 1501 ThreeWay: []byte(` 1502 $setElementOrder/mergingList: 1503 - name: 1 1504 - name: 2 1505 mergingList: 1506 - name: 1 1507 value: 1 1508 `), 1509 Result: []byte(` 1510 mergingList: 1511 - name: 1 1512 value: 1 1513 other: a 1514 - name: 2 1515 value: 2 1516 other: b 1517 `), 1518 }, 1519 }, 1520 { 1521 Description: "add field to map in merging list", 1522 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 1523 Original: []byte(` 1524 mergingList: 1525 - name: 1 1526 - name: 2 1527 value: 2 1528 `), 1529 TwoWay: []byte(` 1530 $setElementOrder/mergingList: 1531 - name: 1 1532 - name: 2 1533 mergingList: 1534 - name: 1 1535 value: 1 1536 `), 1537 Modified: []byte(` 1538 mergingList: 1539 - name: 1 1540 value: 1 1541 - name: 2 1542 value: 2 1543 `), 1544 Current: []byte(` 1545 mergingList: 1546 - name: 1 1547 other: a 1548 - name: 2 1549 value: 2 1550 other: b 1551 `), 1552 ThreeWay: []byte(` 1553 $setElementOrder/mergingList: 1554 - name: 1 1555 - name: 2 1556 mergingList: 1557 - name: 1 1558 value: 1 1559 `), 1560 Result: []byte(` 1561 mergingList: 1562 - name: 1 1563 value: 1 1564 other: a 1565 - name: 2 1566 value: 2 1567 other: b 1568 `), 1569 }, 1570 }, 1571 { 1572 Description: "add field to map in merging list with conflict", 1573 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 1574 Original: []byte(` 1575 mergingList: 1576 - name: 1 1577 - name: 2 1578 value: 2 1579 `), 1580 TwoWay: []byte(` 1581 $setElementOrder/mergingList: 1582 - name: 1 1583 - name: 2 1584 mergingList: 1585 - name: 1 1586 value: 1 1587 `), 1588 Modified: []byte(` 1589 mergingList: 1590 - name: 1 1591 value: 1 1592 - name: 2 1593 value: 2 1594 `), 1595 Current: []byte(` 1596 mergingList: 1597 - name: 1 1598 other: a 1599 - name: 3 1600 value: 2 1601 other: b 1602 `), 1603 ThreeWay: []byte(` 1604 $setElementOrder/mergingList: 1605 - name: 1 1606 - name: 2 1607 mergingList: 1608 - name: 1 1609 value: 1 1610 - name: 2 1611 value: 2 1612 `), 1613 Result: []byte(` 1614 mergingList: 1615 - name: 1 1616 value: 1 1617 other: a 1618 - name: 2 1619 value: 2 1620 - name: 3 1621 value: 2 1622 other: b 1623 `), 1624 }, 1625 }, 1626 { 1627 Description: "add duplicate field to map in merging list", 1628 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 1629 Original: []byte(` 1630 mergingList: 1631 - name: 1 1632 - name: 2 1633 value: 2 1634 `), 1635 TwoWay: []byte(` 1636 $setElementOrder/mergingList: 1637 - name: 1 1638 - name: 2 1639 mergingList: 1640 - name: 1 1641 value: 1 1642 `), 1643 Modified: []byte(` 1644 mergingList: 1645 - name: 1 1646 value: 1 1647 - name: 2 1648 value: 2 1649 `), 1650 Current: []byte(` 1651 mergingList: 1652 - name: 1 1653 value: 1 1654 other: a 1655 - name: 2 1656 value: 2 1657 other: b 1658 `), 1659 ThreeWay: []byte(`{}`), 1660 Result: []byte(` 1661 mergingList: 1662 - name: 1 1663 value: 1 1664 other: a 1665 - name: 2 1666 value: 2 1667 other: b 1668 `), 1669 }, 1670 }, 1671 { 1672 Description: "add an item that already exists in current object in merging list", 1673 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 1674 Original: []byte(` 1675 mergingList: 1676 - name: 1 1677 value: a 1678 - name: 2 1679 `), 1680 TwoWay: []byte(` 1681 $setElementOrder/mergingList: 1682 - name: 1 1683 - name: 2 1684 - name: 3 1685 mergingList: 1686 - name: 3 1687 `), 1688 Modified: []byte(` 1689 mergingList: 1690 - name: 1 1691 value: a 1692 - name: 2 1693 - name: 3 1694 `), 1695 Current: []byte(` 1696 mergingList: 1697 - name: 1 1698 value: a 1699 other: x 1700 - name: 2 1701 - name: 3 1702 `), 1703 ThreeWay: []byte(`{}`), 1704 Result: []byte(` 1705 mergingList: 1706 - name: 1 1707 value: a 1708 other: x 1709 - name: 2 1710 - name: 3 1711 `), 1712 }, 1713 }, 1714 { 1715 Description: "add duplicate field to map in merging list with conflict", 1716 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 1717 Original: []byte(` 1718 mergingList: 1719 - name: 1 1720 - name: 2 1721 value: 2 1722 `), 1723 TwoWay: []byte(` 1724 $setElementOrder/mergingList: 1725 - name: 1 1726 - name: 2 1727 mergingList: 1728 - name: 1 1729 value: 1 1730 `), 1731 Modified: []byte(` 1732 mergingList: 1733 - name: 1 1734 value: 1 1735 - name: 2 1736 value: 2 1737 `), 1738 Current: []byte(` 1739 mergingList: 1740 - name: 1 1741 value: 1 1742 other: a 1743 - name: 2 1744 value: 3 1745 other: b 1746 `), 1747 ThreeWay: []byte(` 1748 $setElementOrder/mergingList: 1749 - name: 1 1750 - name: 2 1751 mergingList: 1752 - name: 2 1753 value: 2 1754 `), 1755 Result: []byte(` 1756 mergingList: 1757 - name: 1 1758 value: 1 1759 other: a 1760 - name: 2 1761 value: 2 1762 other: b 1763 `), 1764 }, 1765 }, 1766 { 1767 Description: "replace map field value in merging list", 1768 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 1769 Original: []byte(` 1770 mergingList: 1771 - name: 1 1772 value: 1 1773 - name: 2 1774 value: 2 1775 `), 1776 TwoWay: []byte(` 1777 $setElementOrder/mergingList: 1778 - name: 1 1779 - name: 2 1780 mergingList: 1781 - name: 1 1782 value: a 1783 `), 1784 Modified: []byte(` 1785 mergingList: 1786 - name: 1 1787 value: a 1788 - name: 2 1789 value: 2 1790 `), 1791 Current: []byte(` 1792 mergingList: 1793 - name: 1 1794 value: 1 1795 other: a 1796 - name: 2 1797 value: 2 1798 other: b 1799 `), 1800 ThreeWay: []byte(` 1801 $setElementOrder/mergingList: 1802 - name: 1 1803 - name: 2 1804 mergingList: 1805 - name: 1 1806 value: a 1807 `), 1808 Result: []byte(` 1809 mergingList: 1810 - name: 1 1811 value: a 1812 other: a 1813 - name: 2 1814 value: 2 1815 other: b 1816 `), 1817 }, 1818 }, 1819 { 1820 Description: "replace map field value in merging list with conflict", 1821 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 1822 Original: []byte(` 1823 mergingList: 1824 - name: 1 1825 value: 1 1826 - name: 2 1827 value: 2 1828 `), 1829 TwoWay: []byte(` 1830 $setElementOrder/mergingList: 1831 - name: 1 1832 - name: 2 1833 mergingList: 1834 - name: 1 1835 value: a 1836 `), 1837 Modified: []byte(` 1838 mergingList: 1839 - name: 1 1840 value: a 1841 - name: 2 1842 value: 2 1843 `), 1844 Current: []byte(` 1845 mergingList: 1846 - name: 1 1847 value: 3 1848 other: a 1849 - name: 2 1850 value: 2 1851 other: b 1852 `), 1853 ThreeWay: []byte(` 1854 $setElementOrder/mergingList: 1855 - name: 1 1856 - name: 2 1857 mergingList: 1858 - name: 1 1859 value: a 1860 `), 1861 Result: []byte(` 1862 mergingList: 1863 - name: 1 1864 value: a 1865 other: a 1866 - name: 2 1867 value: 2 1868 other: b 1869 `), 1870 }, 1871 }, 1872 { 1873 Description: "delete map from merging list", 1874 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 1875 Original: []byte(` 1876 mergingList: 1877 - name: 1 1878 - name: 2 1879 `), 1880 TwoWay: []byte(` 1881 $setElementOrder/mergingList: 1882 - name: 2 1883 mergingList: 1884 - name: 1 1885 $patch: delete 1886 `), 1887 Modified: []byte(` 1888 mergingList: 1889 - name: 2 1890 `), 1891 Current: []byte(` 1892 mergingList: 1893 - name: 1 1894 - name: 2 1895 other: b 1896 `), 1897 ThreeWay: []byte(` 1898 $setElementOrder/mergingList: 1899 - name: 2 1900 mergingList: 1901 - name: 1 1902 $patch: delete 1903 `), 1904 Result: []byte(` 1905 mergingList: 1906 - name: 2 1907 other: b 1908 `), 1909 }, 1910 }, 1911 { 1912 Description: "delete map from merging list with conflict", 1913 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 1914 Original: []byte(` 1915 mergingList: 1916 - name: 1 1917 - name: 2 1918 `), 1919 TwoWay: []byte(` 1920 $setElementOrder/mergingList: 1921 - name: 2 1922 mergingList: 1923 - name: 1 1924 $patch: delete 1925 `), 1926 Modified: []byte(` 1927 mergingList: 1928 - name: 2 1929 `), 1930 Current: []byte(` 1931 mergingList: 1932 - name: 1 1933 other: a 1934 - name: 2 1935 other: b 1936 `), 1937 ThreeWay: []byte(` 1938 $setElementOrder/mergingList: 1939 - name: 2 1940 mergingList: 1941 - name: 1 1942 $patch: delete 1943 `), 1944 Result: []byte(` 1945 mergingList: 1946 - name: 2 1947 other: b 1948 `), 1949 }, 1950 }, 1951 { 1952 Description: "delete missing map from merging list", 1953 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 1954 Original: []byte(` 1955 mergingList: 1956 - name: 1 1957 - name: 2 1958 `), 1959 TwoWay: []byte(` 1960 $setElementOrder/mergingList: 1961 - name: 2 1962 mergingList: 1963 - name: 1 1964 $patch: delete 1965 `), 1966 Modified: []byte(` 1967 mergingList: 1968 - name: 2 1969 `), 1970 Current: []byte(` 1971 mergingList: 1972 - name: 2 1973 other: b 1974 `), 1975 ThreeWay: []byte(` 1976 $setElementOrder/mergingList: 1977 - name: 2 1978 mergingList: 1979 - name: 1 1980 $patch: delete 1981 `), 1982 Result: []byte(` 1983 mergingList: 1984 - name: 2 1985 other: b 1986 `), 1987 }, 1988 }, 1989 { 1990 Description: "delete missing map from merging list with conflict", 1991 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 1992 Original: []byte(` 1993 mergingList: 1994 - name: 1 1995 - name: 2 1996 `), 1997 TwoWay: []byte(` 1998 $setElementOrder/mergingList: 1999 - name: 2 2000 mergingList: 2001 - name: 1 2002 $patch: delete 2003 `), 2004 Modified: []byte(` 2005 mergingList: 2006 - name: 2 2007 `), 2008 Current: []byte(` 2009 mergingList: 2010 - name: 3 2011 other: a 2012 `), 2013 ThreeWay: []byte(` 2014 $setElementOrder/mergingList: 2015 - name: 2 2016 mergingList: 2017 - name: 2 2018 - name: 1 2019 $patch: delete 2020 `), 2021 Result: []byte(` 2022 mergingList: 2023 - name: 2 2024 - name: 3 2025 other: a 2026 `), 2027 }, 2028 }, 2029 { 2030 Description: "add map and delete map from merging list", 2031 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 2032 Original: []byte(` 2033 mergingList: 2034 - name: 1 2035 - name: 2 2036 `), 2037 TwoWay: []byte(` 2038 $setElementOrder/mergingList: 2039 - name: 2 2040 - name: 3 2041 mergingList: 2042 - name: 3 2043 - name: 1 2044 $patch: delete 2045 `), 2046 Modified: []byte(` 2047 mergingList: 2048 - name: 2 2049 - name: 3 2050 `), 2051 Current: []byte(` 2052 mergingList: 2053 - name: 1 2054 - name: 2 2055 other: b 2056 - name: 4 2057 other: c 2058 `), 2059 ThreeWay: []byte(` 2060 $setElementOrder/mergingList: 2061 - name: 2 2062 - name: 3 2063 mergingList: 2064 - name: 3 2065 - name: 1 2066 $patch: delete 2067 `), 2068 Result: []byte(` 2069 mergingList: 2070 - name: 2 2071 other: b 2072 - name: 4 2073 other: c 2074 - name: 3 2075 `), 2076 }, 2077 }, 2078 { 2079 Description: "add map and delete map from merging list with conflict", 2080 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 2081 Original: []byte(` 2082 mergingList: 2083 - name: 1 2084 - name: 2 2085 `), 2086 TwoWay: []byte(` 2087 $setElementOrder/mergingList: 2088 - name: 2 2089 - name: 3 2090 mergingList: 2091 - name: 3 2092 - name: 1 2093 $patch: delete 2094 `), 2095 Modified: []byte(` 2096 mergingList: 2097 - name: 2 2098 - name: 3 2099 `), 2100 Current: []byte(` 2101 mergingList: 2102 - name: 1 2103 other: a 2104 - name: 4 2105 other: c 2106 `), 2107 ThreeWay: []byte(` 2108 $setElementOrder/mergingList: 2109 - name: 2 2110 - name: 3 2111 mergingList: 2112 - name: 2 2113 - name: 3 2114 - name: 1 2115 $patch: delete 2116 `), 2117 Result: []byte(` 2118 mergingList: 2119 - name: 4 2120 other: c 2121 - name: 2 2122 - name: 3 2123 `), 2124 }, 2125 }, 2126 { 2127 Description: "delete field from map in merging list", 2128 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 2129 Original: []byte(` 2130 mergingList: 2131 - name: 1 2132 value: 1 2133 - name: 2 2134 value: 2 2135 `), 2136 TwoWay: []byte(` 2137 $setElementOrder/mergingList: 2138 - name: 1 2139 - name: 2 2140 mergingList: 2141 - name: 1 2142 value: null 2143 `), 2144 Modified: []byte(` 2145 mergingList: 2146 - name: 1 2147 - name: 2 2148 value: 2 2149 `), 2150 Current: []byte(` 2151 mergingList: 2152 - name: 1 2153 value: 1 2154 other: a 2155 - name: 2 2156 value: 2 2157 other: b 2158 `), 2159 ThreeWay: []byte(` 2160 $setElementOrder/mergingList: 2161 - name: 1 2162 - name: 2 2163 mergingList: 2164 - name: 1 2165 value: null 2166 `), 2167 Result: []byte(` 2168 mergingList: 2169 - name: 1 2170 other: a 2171 - name: 2 2172 value: 2 2173 other: b 2174 `), 2175 }, 2176 }, 2177 { 2178 Description: "delete field from map in merging list with conflict", 2179 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 2180 Original: []byte(` 2181 mergingList: 2182 - name: 1 2183 value: 1 2184 - name: 2 2185 value: 2 2186 `), 2187 TwoWay: []byte(` 2188 $setElementOrder/mergingList: 2189 - name: 1 2190 - name: 2 2191 mergingList: 2192 - name: 1 2193 value: null 2194 `), 2195 Modified: []byte(` 2196 mergingList: 2197 - name: 1 2198 - name: 2 2199 value: 2 2200 `), 2201 Current: []byte(` 2202 mergingList: 2203 - name: 1 2204 value: a 2205 other: a 2206 - name: 2 2207 value: 2 2208 `), 2209 ThreeWay: []byte(` 2210 $setElementOrder/mergingList: 2211 - name: 1 2212 - name: 2 2213 mergingList: 2214 - name: 1 2215 value: null 2216 `), 2217 Result: []byte(` 2218 mergingList: 2219 - name: 1 2220 other: a 2221 - name: 2 2222 value: 2 2223 `), 2224 }, 2225 }, 2226 { 2227 Description: "delete missing field from map in merging list", 2228 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 2229 Original: []byte(` 2230 mergingList: 2231 - name: 1 2232 value: 1 2233 - name: 2 2234 value: 2 2235 `), 2236 TwoWay: []byte(` 2237 $setElementOrder/mergingList: 2238 - name: 1 2239 - name: 2 2240 mergingList: 2241 - name: 1 2242 value: null 2243 `), 2244 Modified: []byte(` 2245 mergingList: 2246 - name: 1 2247 - name: 2 2248 value: 2 2249 `), 2250 Current: []byte(` 2251 mergingList: 2252 - name: 1 2253 other: a 2254 - name: 2 2255 value: 2 2256 other: b 2257 `), 2258 ThreeWay: []byte(` 2259 $setElementOrder/mergingList: 2260 - name: 1 2261 - name: 2 2262 mergingList: 2263 - name: 1 2264 value: null 2265 `), 2266 Result: []byte(` 2267 mergingList: 2268 - name: 1 2269 other: a 2270 - name: 2 2271 value: 2 2272 other: b 2273 `), 2274 }, 2275 }, 2276 { 2277 Description: "delete missing field from map in merging list with conflict", 2278 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 2279 Original: []byte(` 2280 mergingList: 2281 - name: 1 2282 value: 1 2283 - name: 2 2284 value: 2 2285 `), 2286 TwoWay: []byte(` 2287 $setElementOrder/mergingList: 2288 - name: 1 2289 - name: 2 2290 mergingList: 2291 - name: 1 2292 value: null 2293 `), 2294 Modified: []byte(` 2295 mergingList: 2296 - name: 1 2297 - name: 2 2298 value: 2 2299 `), 2300 Current: []byte(` 2301 mergingList: 2302 - name: 1 2303 other: a 2304 - name: 2 2305 other: b 2306 `), 2307 ThreeWay: []byte(` 2308 $setElementOrder/mergingList: 2309 - name: 1 2310 - name: 2 2311 mergingList: 2312 - name: 1 2313 value: null 2314 - name: 2 2315 value: 2 2316 `), 2317 Result: []byte(` 2318 mergingList: 2319 - name: 1 2320 other: a 2321 - name: 2 2322 value: 2 2323 other: b 2324 `), 2325 }, 2326 }, 2327 { 2328 Description: "replace non merging list nested in merging list", 2329 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 2330 Original: []byte(` 2331 mergingList: 2332 - name: 1 2333 nonMergingList: 2334 - name: 1 2335 - name: 2 2336 value: 2 2337 - name: 2 2338 `), 2339 TwoWay: []byte(` 2340 $setElementOrder/mergingList: 2341 - name: 1 2342 - name: 2 2343 mergingList: 2344 - name: 1 2345 nonMergingList: 2346 - name: 1 2347 value: 1 2348 `), 2349 Modified: []byte(` 2350 mergingList: 2351 - name: 1 2352 nonMergingList: 2353 - name: 1 2354 value: 1 2355 - name: 2 2356 `), 2357 Current: []byte(` 2358 mergingList: 2359 - name: 1 2360 other: a 2361 nonMergingList: 2362 - name: 1 2363 - name: 2 2364 value: 2 2365 - name: 2 2366 other: b 2367 `), 2368 ThreeWay: []byte(` 2369 $setElementOrder/mergingList: 2370 - name: 1 2371 - name: 2 2372 mergingList: 2373 - name: 1 2374 nonMergingList: 2375 - name: 1 2376 value: 1 2377 `), 2378 Result: []byte(` 2379 mergingList: 2380 - name: 1 2381 other: a 2382 nonMergingList: 2383 - name: 1 2384 value: 1 2385 - name: 2 2386 other: b 2387 `), 2388 }, 2389 }, 2390 { 2391 Description: "replace non merging list nested in merging list with value conflict", 2392 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 2393 Original: []byte(` 2394 mergingList: 2395 - name: 1 2396 nonMergingList: 2397 - name: 1 2398 - name: 2 2399 value: 2 2400 - name: 2 2401 `), 2402 TwoWay: []byte(` 2403 $setElementOrder/mergingList: 2404 - name: 1 2405 - name: 2 2406 mergingList: 2407 - name: 1 2408 nonMergingList: 2409 - name: 1 2410 value: 1 2411 `), 2412 Modified: []byte(` 2413 mergingList: 2414 - name: 1 2415 nonMergingList: 2416 - name: 1 2417 value: 1 2418 - name: 2 2419 `), 2420 Current: []byte(` 2421 mergingList: 2422 - name: 1 2423 other: a 2424 nonMergingList: 2425 - name: 1 2426 value: c 2427 - name: 2 2428 other: b 2429 `), 2430 ThreeWay: []byte(` 2431 $setElementOrder/mergingList: 2432 - name: 1 2433 - name: 2 2434 mergingList: 2435 - name: 1 2436 nonMergingList: 2437 - name: 1 2438 value: 1 2439 `), 2440 Result: []byte(` 2441 mergingList: 2442 - name: 1 2443 other: a 2444 nonMergingList: 2445 - name: 1 2446 value: 1 2447 - name: 2 2448 other: b 2449 `), 2450 }, 2451 }, 2452 { 2453 Description: "replace non merging list nested in merging list with deletion conflict", 2454 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 2455 Original: []byte(` 2456 mergingList: 2457 - name: 1 2458 nonMergingList: 2459 - name: 1 2460 - name: 2 2461 value: 2 2462 - name: 2 2463 `), 2464 TwoWay: []byte(` 2465 $setElementOrder/mergingList: 2466 - name: 1 2467 - name: 2 2468 mergingList: 2469 - name: 1 2470 nonMergingList: 2471 - name: 1 2472 value: 1 2473 `), 2474 Modified: []byte(` 2475 mergingList: 2476 - name: 1 2477 nonMergingList: 2478 - name: 1 2479 value: 1 2480 - name: 2 2481 `), 2482 Current: []byte(` 2483 mergingList: 2484 - name: 1 2485 other: a 2486 nonMergingList: 2487 - name: 2 2488 value: 2 2489 - name: 2 2490 other: b 2491 `), 2492 ThreeWay: []byte(` 2493 $setElementOrder/mergingList: 2494 - name: 1 2495 - name: 2 2496 mergingList: 2497 - name: 1 2498 nonMergingList: 2499 - name: 1 2500 value: 1 2501 `), 2502 Result: []byte(` 2503 mergingList: 2504 - name: 1 2505 other: a 2506 nonMergingList: 2507 - name: 1 2508 value: 1 2509 - name: 2 2510 other: b 2511 `), 2512 }, 2513 }, 2514 { 2515 Description: "add field to map in merging list nested in merging list", 2516 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 2517 Original: []byte(` 2518 mergingList: 2519 - name: 1 2520 mergingList: 2521 - name: 1 2522 - name: 2 2523 value: 2 2524 - name: 2 2525 `), 2526 TwoWay: []byte(` 2527 $setElementOrder/mergingList: 2528 - name: 1 2529 - name: 2 2530 mergingList: 2531 - $setElementOrder/mergingList: 2532 - name: 1 2533 - name: 2 2534 name: 1 2535 mergingList: 2536 - name: 1 2537 value: 1 2538 `), 2539 Modified: []byte(` 2540 mergingList: 2541 - name: 1 2542 mergingList: 2543 - name: 1 2544 value: 1 2545 - name: 2 2546 value: 2 2547 - name: 2 2548 `), 2549 Current: []byte(` 2550 mergingList: 2551 - name: 1 2552 other: a 2553 mergingList: 2554 - name: 1 2555 - name: 2 2556 value: 2 2557 - name: 2 2558 other: b 2559 `), 2560 ThreeWay: []byte(` 2561 $setElementOrder/mergingList: 2562 - name: 1 2563 - name: 2 2564 mergingList: 2565 - $setElementOrder/mergingList: 2566 - name: 1 2567 - name: 2 2568 name: 1 2569 mergingList: 2570 - name: 1 2571 value: 1 2572 `), 2573 Result: []byte(` 2574 mergingList: 2575 - name: 1 2576 other: a 2577 mergingList: 2578 - name: 1 2579 value: 1 2580 - name: 2 2581 value: 2 2582 - name: 2 2583 other: b 2584 `), 2585 }, 2586 }, 2587 { 2588 Description: "add field to map in merging list nested in merging list with value conflict", 2589 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 2590 Original: []byte(` 2591 mergingList: 2592 - name: 1 2593 mergingList: 2594 - name: 1 2595 - name: 2 2596 value: 2 2597 - name: 2 2598 `), 2599 TwoWay: []byte(` 2600 $setElementOrder/mergingList: 2601 - name: 1 2602 - name: 2 2603 mergingList: 2604 - $setElementOrder/mergingList: 2605 - name: 1 2606 - name: 2 2607 name: 1 2608 mergingList: 2609 - name: 1 2610 value: 1 2611 `), 2612 Modified: []byte(` 2613 mergingList: 2614 - name: 1 2615 mergingList: 2616 - name: 1 2617 value: 1 2618 - name: 2 2619 value: 2 2620 - name: 2 2621 `), 2622 Current: []byte(` 2623 mergingList: 2624 - name: 1 2625 other: a 2626 mergingList: 2627 - name: 1 2628 value: a 2629 other: c 2630 - name: 2 2631 value: b 2632 other: d 2633 - name: 2 2634 other: b 2635 `), 2636 ThreeWay: []byte(` 2637 $setElementOrder/mergingList: 2638 - name: 1 2639 - name: 2 2640 mergingList: 2641 - $setElementOrder/mergingList: 2642 - name: 1 2643 - name: 2 2644 name: 1 2645 mergingList: 2646 - name: 1 2647 value: 1 2648 - name: 2 2649 value: 2 2650 `), 2651 Result: []byte(` 2652 mergingList: 2653 - name: 1 2654 other: a 2655 mergingList: 2656 - name: 1 2657 value: 1 2658 other: c 2659 - name: 2 2660 value: 2 2661 other: d 2662 - name: 2 2663 other: b 2664 `), 2665 }, 2666 }, 2667 { 2668 Description: "add field to map in merging list nested in merging list with deletion conflict", 2669 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 2670 Original: []byte(` 2671 mergingList: 2672 - name: 1 2673 mergingList: 2674 - name: 1 2675 - name: 2 2676 value: 2 2677 - name: 2 2678 `), 2679 TwoWay: []byte(` 2680 $setElementOrder/mergingList: 2681 - name: 1 2682 - name: 2 2683 mergingList: 2684 - $setElementOrder/mergingList: 2685 - name: 1 2686 - name: 2 2687 name: 1 2688 mergingList: 2689 - name: 1 2690 value: 1 2691 `), 2692 Modified: []byte(` 2693 mergingList: 2694 - name: 1 2695 mergingList: 2696 - name: 1 2697 value: 1 2698 - name: 2 2699 value: 2 2700 - name: 2 2701 `), 2702 Current: []byte(` 2703 mergingList: 2704 - name: 1 2705 other: a 2706 mergingList: 2707 - name: 2 2708 value: 2 2709 other: d 2710 - name: 2 2711 other: b 2712 `), 2713 ThreeWay: []byte(` 2714 $setElementOrder/mergingList: 2715 - name: 1 2716 - name: 2 2717 mergingList: 2718 - $setElementOrder/mergingList: 2719 - name: 1 2720 - name: 2 2721 name: 1 2722 mergingList: 2723 - name: 1 2724 value: 1 2725 `), 2726 Result: []byte(` 2727 mergingList: 2728 - name: 1 2729 other: a 2730 mergingList: 2731 - name: 1 2732 value: 1 2733 - name: 2 2734 value: 2 2735 other: d 2736 - name: 2 2737 other: b 2738 `), 2739 }, 2740 }, 2741 2742 { 2743 Description: "add field to map in merging list nested in merging list with deletion conflict", 2744 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 2745 Original: []byte(` 2746 mergingList: 2747 - name: 1 2748 mergingList: 2749 - name: 1 2750 - name: 2 2751 value: 2 2752 - name: 2 2753 `), 2754 TwoWay: []byte(` 2755 $setElementOrder/mergingList: 2756 - name: 1 2757 - name: 2 2758 mergingList: 2759 - $setElementOrder/mergingList: 2760 - name: 2 2761 - name: 1 2762 name: 1 2763 mergingList: 2764 - name: 1 2765 value: 1 2766 `), 2767 Modified: []byte(` 2768 mergingList: 2769 - name: 1 2770 mergingList: 2771 - name: 2 2772 value: 2 2773 - name: 1 2774 value: 1 2775 - name: 2 2776 `), 2777 Current: []byte(` 2778 mergingList: 2779 - name: 1 2780 other: a 2781 mergingList: 2782 - name: 2 2783 value: 2 2784 other: d 2785 - name: 2 2786 other: b 2787 `), 2788 ThreeWay: []byte(` 2789 $setElementOrder/mergingList: 2790 - name: 1 2791 - name: 2 2792 mergingList: 2793 - $setElementOrder/mergingList: 2794 - name: 2 2795 - name: 1 2796 name: 1 2797 mergingList: 2798 - name: 1 2799 value: 1 2800 `), 2801 Result: []byte(` 2802 mergingList: 2803 - name: 1 2804 other: a 2805 mergingList: 2806 - name: 2 2807 value: 2 2808 other: d 2809 - name: 1 2810 value: 1 2811 - name: 2 2812 other: b 2813 `), 2814 }, 2815 }, 2816 { 2817 Description: "add map to merging list by pointer", 2818 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 2819 Original: []byte(` 2820 mergeItemPtr: 2821 - name: 1 2822 `), 2823 TwoWay: []byte(` 2824 $setElementOrder/mergeItemPtr: 2825 - name: 1 2826 - name: 2 2827 mergeItemPtr: 2828 - name: 2 2829 `), 2830 Modified: []byte(` 2831 mergeItemPtr: 2832 - name: 1 2833 - name: 2 2834 `), 2835 Current: []byte(` 2836 mergeItemPtr: 2837 - name: 1 2838 other: a 2839 - name: 3 2840 `), 2841 ThreeWay: []byte(` 2842 $setElementOrder/mergeItemPtr: 2843 - name: 1 2844 - name: 2 2845 mergeItemPtr: 2846 - name: 2 2847 `), 2848 Result: []byte(` 2849 mergeItemPtr: 2850 - name: 1 2851 other: a 2852 - name: 2 2853 - name: 3 2854 `), 2855 }, 2856 }, 2857 { 2858 Description: "add map to merging list by pointer with conflict", 2859 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 2860 Original: []byte(` 2861 mergeItemPtr: 2862 - name: 1 2863 `), 2864 TwoWay: []byte(` 2865 $setElementOrder/mergeItemPtr: 2866 - name: 1 2867 - name: 2 2868 mergeItemPtr: 2869 - name: 2 2870 `), 2871 Modified: []byte(` 2872 mergeItemPtr: 2873 - name: 1 2874 - name: 2 2875 `), 2876 Current: []byte(` 2877 mergeItemPtr: 2878 - name: 3 2879 `), 2880 ThreeWay: []byte(` 2881 $setElementOrder/mergeItemPtr: 2882 - name: 1 2883 - name: 2 2884 mergeItemPtr: 2885 - name: 1 2886 - name: 2 2887 `), 2888 Result: []byte(` 2889 mergeItemPtr: 2890 - name: 1 2891 - name: 2 2892 - name: 3 2893 `), 2894 }, 2895 }, 2896 { 2897 Description: "add field to map in merging list by pointer", 2898 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 2899 Original: []byte(` 2900 mergeItemPtr: 2901 - name: 1 2902 mergeItemPtr: 2903 - name: 1 2904 - name: 2 2905 value: 2 2906 - name: 2 2907 `), 2908 TwoWay: []byte(` 2909 $setElementOrder/mergeItemPtr: 2910 - name: 1 2911 - name: 2 2912 mergeItemPtr: 2913 - $setElementOrder/mergeItemPtr: 2914 - name: 1 2915 - name: 2 2916 name: 1 2917 mergeItemPtr: 2918 - name: 1 2919 value: 1 2920 `), 2921 Modified: []byte(` 2922 mergeItemPtr: 2923 - name: 1 2924 mergeItemPtr: 2925 - name: 1 2926 value: 1 2927 - name: 2 2928 value: 2 2929 - name: 2 2930 `), 2931 Current: []byte(` 2932 mergeItemPtr: 2933 - name: 1 2934 other: a 2935 mergeItemPtr: 2936 - name: 1 2937 other: a 2938 - name: 2 2939 value: 2 2940 other: b 2941 - name: 2 2942 other: b 2943 `), 2944 ThreeWay: []byte(` 2945 $setElementOrder/mergeItemPtr: 2946 - name: 1 2947 - name: 2 2948 mergeItemPtr: 2949 - $setElementOrder/mergeItemPtr: 2950 - name: 1 2951 - name: 2 2952 name: 1 2953 mergeItemPtr: 2954 - name: 1 2955 value: 1 2956 `), 2957 Result: []byte(` 2958 mergeItemPtr: 2959 - name: 1 2960 other: a 2961 mergeItemPtr: 2962 - name: 1 2963 value: 1 2964 other: a 2965 - name: 2 2966 value: 2 2967 other: b 2968 - name: 2 2969 other: b 2970 `), 2971 }, 2972 }, 2973 { 2974 Description: "add field to map in merging list by pointer with conflict", 2975 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 2976 Original: []byte(` 2977 mergeItemPtr: 2978 - name: 1 2979 mergeItemPtr: 2980 - name: 1 2981 - name: 2 2982 value: 2 2983 - name: 2 2984 `), 2985 TwoWay: []byte(` 2986 $setElementOrder/mergeItemPtr: 2987 - name: 1 2988 - name: 2 2989 mergeItemPtr: 2990 - $setElementOrder/mergeItemPtr: 2991 - name: 1 2992 - name: 2 2993 name: 1 2994 mergeItemPtr: 2995 - name: 1 2996 value: 1 2997 `), 2998 Modified: []byte(` 2999 mergeItemPtr: 3000 - name: 1 3001 mergeItemPtr: 3002 - name: 1 3003 value: 1 3004 - name: 2 3005 value: 2 3006 - name: 2 3007 `), 3008 Current: []byte(` 3009 mergeItemPtr: 3010 - name: 1 3011 other: a 3012 mergeItemPtr: 3013 - name: 1 3014 value: a 3015 - name: 2 3016 value: 2 3017 other: b 3018 - name: 2 3019 other: b 3020 `), 3021 ThreeWay: []byte(` 3022 $setElementOrder/mergeItemPtr: 3023 - name: 1 3024 - name: 2 3025 mergeItemPtr: 3026 - $setElementOrder/mergeItemPtr: 3027 - name: 1 3028 - name: 2 3029 name: 1 3030 mergeItemPtr: 3031 - name: 1 3032 value: 1 3033 `), 3034 Result: []byte(` 3035 mergeItemPtr: 3036 - name: 1 3037 other: a 3038 mergeItemPtr: 3039 - name: 1 3040 value: 1 3041 - name: 2 3042 value: 2 3043 other: b 3044 - name: 2 3045 other: b 3046 `), 3047 }, 3048 }, 3049 { 3050 Description: "merge lists of scalars", 3051 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 3052 Original: []byte(` 3053 mergingIntList: 3054 - 1 3055 - 2 3056 `), 3057 TwoWay: []byte(` 3058 $setElementOrder/mergingIntList: 3059 - 1 3060 - 2 3061 - 3 3062 mergingIntList: 3063 - 3 3064 `), 3065 Modified: []byte(` 3066 mergingIntList: 3067 - 1 3068 - 2 3069 - 3 3070 `), 3071 Current: []byte(` 3072 mergingIntList: 3073 - 1 3074 - 2 3075 - 4 3076 `), 3077 ThreeWay: []byte(` 3078 $setElementOrder/mergingIntList: 3079 - 1 3080 - 2 3081 - 3 3082 mergingIntList: 3083 - 3 3084 `), 3085 Result: []byte(` 3086 mergingIntList: 3087 - 1 3088 - 2 3089 - 3 3090 - 4 3091 `), 3092 }, 3093 }, 3094 { 3095 Description: "add duplicate field to map in merging int list", 3096 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 3097 Original: []byte(` 3098 mergingIntList: 3099 - 1 3100 - 2 3101 `), 3102 TwoWay: []byte(` 3103 $setElementOrder/mergingIntList: 3104 - 1 3105 - 2 3106 - 3 3107 mergingIntList: 3108 - 3 3109 `), 3110 Modified: []byte(` 3111 mergingIntList: 3112 - 1 3113 - 2 3114 - 3 3115 `), 3116 Current: []byte(` 3117 mergingIntList: 3118 - 1 3119 - 2 3120 - 3 3121 `), 3122 ThreeWay: []byte(`{}`), 3123 Result: []byte(` 3124 mergingIntList: 3125 - 1 3126 - 2 3127 - 3 3128 `), 3129 }, 3130 }, 3131 // test case for setElementOrder 3132 { 3133 Description: "add an item in a list of primitives and preserve order", 3134 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 3135 Original: []byte(` 3136 mergingIntList: 3137 - 1 3138 - 2 3139 `), 3140 TwoWay: []byte(` 3141 $setElementOrder/mergingIntList: 3142 - 3 3143 - 1 3144 - 2 3145 mergingIntList: 3146 - 3 3147 `), 3148 Modified: []byte(` 3149 mergingIntList: 3150 - 3 3151 - 1 3152 - 2 3153 `), 3154 Current: []byte(` 3155 mergingIntList: 3156 - 1 3157 - 4 3158 - 2 3159 `), 3160 ThreeWay: []byte(` 3161 $setElementOrder/mergingIntList: 3162 - 3 3163 - 1 3164 - 2 3165 mergingIntList: 3166 - 3 3167 `), 3168 Result: []byte(` 3169 mergingIntList: 3170 - 3 3171 - 1 3172 - 4 3173 - 2 3174 `), 3175 }, 3176 }, 3177 { 3178 Description: "delete an item in a list of primitives and preserve order", 3179 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 3180 Original: []byte(` 3181 mergingIntList: 3182 - 1 3183 - 2 3184 - 3 3185 `), 3186 TwoWay: []byte(` 3187 $setElementOrder/mergingIntList: 3188 - 2 3189 - 1 3190 $deleteFromPrimitiveList/mergingIntList: 3191 - 3 3192 `), 3193 Modified: []byte(` 3194 mergingIntList: 3195 - 2 3196 - 1 3197 `), 3198 Current: []byte(` 3199 mergingIntList: 3200 - 1 3201 - 2 3202 - 3 3203 `), 3204 ThreeWay: []byte(` 3205 $setElementOrder/mergingIntList: 3206 - 2 3207 - 1 3208 $deleteFromPrimitiveList/mergingIntList: 3209 - 3 3210 `), 3211 Result: []byte(` 3212 mergingIntList: 3213 - 2 3214 - 1 3215 `), 3216 }, 3217 }, 3218 { 3219 Description: "add an item in a list and preserve order", 3220 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 3221 Original: []byte(` 3222 mergingList: 3223 - name: 1 3224 - name: 2 3225 value: 2 3226 `), 3227 TwoWay: []byte(` 3228 $setElementOrder/mergingList: 3229 - name: 3 3230 - name: 1 3231 - name: 2 3232 mergingList: 3233 - name: 3 3234 value: 3 3235 `), 3236 Modified: []byte(` 3237 mergingList: 3238 - name: 3 3239 value: 3 3240 - name: 1 3241 - name: 2 3242 value: 2 3243 `), 3244 Current: []byte(` 3245 mergingList: 3246 - name: 1 3247 other: a 3248 - name: 2 3249 value: 2 3250 other: b 3251 `), 3252 ThreeWay: []byte(` 3253 $setElementOrder/mergingList: 3254 - name: 3 3255 - name: 1 3256 - name: 2 3257 mergingList: 3258 - name: 3 3259 value: 3 3260 `), 3261 Result: []byte(` 3262 mergingList: 3263 - name: 3 3264 value: 3 3265 - name: 1 3266 other: a 3267 - name: 2 3268 value: 2 3269 other: b 3270 `), 3271 }, 3272 }, 3273 { 3274 Description: "add multiple items in a list and preserve order", 3275 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 3276 Original: []byte(` 3277 mergingList: 3278 - name: 1 3279 - name: 2 3280 value: 2 3281 `), 3282 TwoWay: []byte(` 3283 $setElementOrder/mergingList: 3284 - name: 1 3285 - name: 4 3286 - name: 2 3287 - name: 3 3288 mergingList: 3289 - name: 4 3290 value: 4 3291 - name: 3 3292 value: 3 3293 `), 3294 Modified: []byte(` 3295 mergingList: 3296 - name: 1 3297 - name: 4 3298 value: 4 3299 - name: 2 3300 value: 2 3301 - name: 3 3302 value: 3 3303 `), 3304 Current: []byte(` 3305 mergingList: 3306 - name: 1 3307 other: a 3308 - name: 2 3309 value: 2 3310 other: b 3311 `), 3312 ThreeWay: []byte(` 3313 $setElementOrder/mergingList: 3314 - name: 1 3315 - name: 4 3316 - name: 2 3317 - name: 3 3318 mergingList: 3319 - name: 4 3320 value: 4 3321 - name: 3 3322 value: 3 3323 `), 3324 Result: []byte(` 3325 mergingList: 3326 - name: 1 3327 other: a 3328 - name: 4 3329 value: 4 3330 - name: 2 3331 value: 2 3332 other: b 3333 - name: 3 3334 value: 3 3335 `), 3336 }, 3337 }, 3338 { 3339 Description: "delete an item in a list and preserve order", 3340 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 3341 Original: []byte(` 3342 mergingList: 3343 - name: 1 3344 - name: 3 3345 value: 3 3346 - name: 2 3347 value: 2 3348 `), 3349 TwoWay: []byte(` 3350 $setElementOrder/mergingList: 3351 - name: 2 3352 - name: 1 3353 mergingList: 3354 - name: 3 3355 $patch: delete 3356 `), 3357 Modified: []byte(` 3358 mergingList: 3359 - name: 2 3360 value: 2 3361 - name: 1 3362 `), 3363 Current: []byte(` 3364 mergingList: 3365 - name: 1 3366 other: a 3367 - name: 2 3368 value: 2 3369 other: b 3370 - name: 3 3371 value: 3 3372 `), 3373 ThreeWay: []byte(` 3374 $setElementOrder/mergingList: 3375 - name: 2 3376 - name: 1 3377 mergingList: 3378 - name: 3 3379 $patch: delete 3380 `), 3381 Result: []byte(` 3382 mergingList: 3383 - name: 2 3384 value: 2 3385 other: b 3386 - name: 1 3387 other: a 3388 `), 3389 }, 3390 }, 3391 { 3392 Description: "change an item in a list and preserve order", 3393 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 3394 Original: []byte(` 3395 mergingList: 3396 - name: 1 3397 - name: 3 3398 value: 3 3399 - name: 2 3400 value: 2 3401 `), 3402 TwoWay: []byte(` 3403 $setElementOrder/mergingList: 3404 - name: 2 3405 - name: 3 3406 - name: 1 3407 mergingList: 3408 - name: 3 3409 value: x 3410 `), 3411 Modified: []byte(` 3412 mergingList: 3413 - name: 2 3414 value: 2 3415 - name: 3 3416 value: x 3417 - name: 1 3418 `), 3419 Current: []byte(` 3420 mergingList: 3421 - name: 1 3422 other: a 3423 - name: 2 3424 value: 2 3425 other: b 3426 - name: 3 3427 value: 3 3428 `), 3429 ThreeWay: []byte(` 3430 $setElementOrder/mergingList: 3431 - name: 2 3432 - name: 3 3433 - name: 1 3434 mergingList: 3435 - name: 3 3436 value: x 3437 `), 3438 Result: []byte(` 3439 mergingList: 3440 - name: 2 3441 value: 2 3442 other: b 3443 - name: 3 3444 value: x 3445 - name: 1 3446 other: a 3447 `), 3448 }, 3449 }, 3450 { 3451 Description: "add and delete an item in a list and preserve order", 3452 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 3453 Original: []byte(` 3454 mergingList: 3455 - name: 1 3456 - name: 3 3457 value: 3 3458 - name: 2 3459 value: 2 3460 `), 3461 TwoWay: []byte(` 3462 $setElementOrder/mergingList: 3463 - name: 4 3464 - name: 2 3465 - name: 1 3466 mergingList: 3467 - name: 4 3468 value: 4 3469 - name: 3 3470 $patch: delete 3471 `), 3472 Modified: []byte(` 3473 mergingList: 3474 - name: 4 3475 value: 4 3476 - name: 2 3477 value: 2 3478 - name: 1 3479 `), 3480 Current: []byte(` 3481 mergingList: 3482 - name: 1 3483 other: a 3484 - name: 2 3485 value: 2 3486 other: b 3487 - name: 3 3488 value: 3 3489 `), 3490 ThreeWay: []byte(` 3491 $setElementOrder/mergingList: 3492 - name: 4 3493 - name: 2 3494 - name: 1 3495 mergingList: 3496 - name: 4 3497 value: 4 3498 - name: 3 3499 $patch: delete 3500 `), 3501 Result: []byte(` 3502 mergingList: 3503 - name: 4 3504 value: 4 3505 - name: 2 3506 value: 2 3507 other: b 3508 - name: 1 3509 other: a 3510 `), 3511 }, 3512 }, 3513 { 3514 Description: "set elements order in a list", 3515 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 3516 Original: []byte(` 3517 mergingList: 3518 - name: 1 3519 - name: 3 3520 value: 3 3521 - name: 4 3522 value: 4 3523 - name: 2 3524 value: 2 3525 `), 3526 TwoWay: []byte(` 3527 $setElementOrder/mergingList: 3528 - name: 4 3529 - name: 2 3530 - name: 3 3531 - name: 1 3532 `), 3533 Modified: []byte(` 3534 mergingList: 3535 - name: 4 3536 value: 4 3537 - name: 2 3538 value: 2 3539 - name: 3 3540 value: 3 3541 - name: 1 3542 `), 3543 Current: []byte(` 3544 mergingList: 3545 - name: 1 3546 other: a 3547 - name: 3 3548 value: 3 3549 - name: 4 3550 value: 4 3551 - name: 2 3552 value: 2 3553 `), 3554 ThreeWay: []byte(` 3555 $setElementOrder/mergingList: 3556 - name: 4 3557 - name: 2 3558 - name: 3 3559 - name: 1 3560 `), 3561 Result: []byte(` 3562 mergingList: 3563 - name: 4 3564 value: 4 3565 - name: 2 3566 value: 2 3567 - name: 3 3568 value: 3 3569 - name: 1 3570 other: a 3571 `), 3572 }, 3573 }, 3574 { 3575 Description: "set elements order in a list with server-only items", 3576 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 3577 Original: []byte(` 3578 mergingList: 3579 - name: 1 3580 - name: 3 3581 value: 3 3582 - name: 4 3583 value: 4 3584 - name: 2 3585 value: 2 3586 `), 3587 TwoWay: []byte(` 3588 $setElementOrder/mergingList: 3589 - name: 4 3590 - name: 2 3591 - name: 3 3592 - name: 1 3593 `), 3594 Modified: []byte(` 3595 mergingList: 3596 - name: 4 3597 value: 4 3598 - name: 2 3599 value: 2 3600 - name: 3 3601 value: 3 3602 - name: 1 3603 `), 3604 Current: []byte(` 3605 mergingList: 3606 - name: 1 3607 other: a 3608 - name: 3 3609 value: 3 3610 - name: 4 3611 value: 4 3612 - name: 2 3613 value: 2 3614 - name: 9 3615 `), 3616 ThreeWay: []byte(` 3617 $setElementOrder/mergingList: 3618 - name: 4 3619 - name: 2 3620 - name: 3 3621 - name: 1 3622 `), 3623 Result: []byte(` 3624 mergingList: 3625 - name: 4 3626 value: 4 3627 - name: 2 3628 value: 2 3629 - name: 3 3630 value: 3 3631 - name: 1 3632 other: a 3633 - name: 9 3634 `), 3635 }, 3636 }, 3637 { 3638 Description: "set elements order in a list with server-only items 2", 3639 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 3640 Original: []byte(` 3641 mergingList: 3642 - name: 1 3643 - name: 2 3644 value: 2 3645 - name: 3 3646 value: 3 3647 - name: 4 3648 value: 4 3649 `), 3650 TwoWay: []byte(` 3651 $setElementOrder/mergingList: 3652 - name: 2 3653 - name: 1 3654 - name: 4 3655 - name: 3 3656 `), 3657 Modified: []byte(` 3658 mergingList: 3659 - name: 2 3660 value: 2 3661 - name: 1 3662 - name: 4 3663 value: 4 3664 - name: 3 3665 value: 3 3666 `), 3667 Current: []byte(` 3668 mergingList: 3669 - name: 1 3670 other: a 3671 - name: 2 3672 value: 2 3673 - name: 9 3674 - name: 3 3675 value: 3 3676 - name: 4 3677 value: 4 3678 `), 3679 ThreeWay: []byte(` 3680 $setElementOrder/mergingList: 3681 - name: 2 3682 - name: 1 3683 - name: 4 3684 - name: 3 3685 `), 3686 Result: []byte(` 3687 mergingList: 3688 - name: 2 3689 value: 2 3690 - name: 1 3691 other: a 3692 - name: 9 3693 - name: 4 3694 value: 4 3695 - name: 3 3696 value: 3 3697 `), 3698 }, 3699 }, 3700 { 3701 Description: "set elements order in a list with server-only items 3", 3702 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 3703 Original: []byte(` 3704 mergingList: 3705 - name: 1 3706 - name: 2 3707 value: 2 3708 - name: 3 3709 value: 3 3710 - name: 4 3711 value: 4 3712 `), 3713 TwoWay: []byte(` 3714 $setElementOrder/mergingList: 3715 - name: 2 3716 - name: 1 3717 - name: 4 3718 - name: 3 3719 `), 3720 Modified: []byte(` 3721 mergingList: 3722 - name: 2 3723 value: 2 3724 - name: 1 3725 - name: 4 3726 value: 4 3727 - name: 3 3728 value: 3 3729 `), 3730 Current: []byte(` 3731 mergingList: 3732 - name: 1 3733 other: a 3734 - name: 2 3735 value: 2 3736 - name: 7 3737 - name: 9 3738 - name: 8 3739 - name: 3 3740 value: 3 3741 - name: 4 3742 value: 4 3743 `), 3744 ThreeWay: []byte(` 3745 $setElementOrder/mergingList: 3746 - name: 2 3747 - name: 1 3748 - name: 4 3749 - name: 3 3750 `), 3751 Result: []byte(` 3752 mergingList: 3753 - name: 2 3754 value: 2 3755 - name: 1 3756 other: a 3757 - name: 7 3758 - name: 9 3759 - name: 8 3760 - name: 4 3761 value: 4 3762 - name: 3 3763 value: 3 3764 `), 3765 }, 3766 }, 3767 { 3768 Description: "add an item in a int list and preserve order", 3769 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 3770 Original: []byte(` 3771 mergingIntList: 3772 - 1 3773 - 2 3774 `), 3775 TwoWay: []byte(` 3776 $setElementOrder/mergingIntList: 3777 - 3 3778 - 1 3779 - 2 3780 mergingIntList: 3781 - 3 3782 `), 3783 Modified: []byte(` 3784 mergingIntList: 3785 - 3 3786 - 1 3787 - 2 3788 `), 3789 Current: []byte(` 3790 mergingIntList: 3791 - 1 3792 - 2 3793 `), 3794 ThreeWay: []byte(` 3795 $setElementOrder/mergingIntList: 3796 - 3 3797 - 1 3798 - 2 3799 mergingIntList: 3800 - 3 3801 `), 3802 Result: []byte(` 3803 mergingIntList: 3804 - 3 3805 - 1 3806 - 2 3807 `), 3808 }, 3809 }, 3810 { 3811 Description: "add multiple items in a int list and preserve order", 3812 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 3813 Original: []byte(` 3814 mergingIntList: 3815 - 1 3816 - 2 3817 `), 3818 TwoWay: []byte(` 3819 $setElementOrder/mergingIntList: 3820 - 1 3821 - 4 3822 - 2 3823 - 3 3824 mergingIntList: 3825 - 4 3826 - 3 3827 `), 3828 Modified: []byte(` 3829 mergingIntList: 3830 - 1 3831 - 4 3832 - 2 3833 - 3 3834 `), 3835 Current: []byte(` 3836 mergingIntList: 3837 - 1 3838 - 2 3839 `), 3840 ThreeWay: []byte(` 3841 $setElementOrder/mergingIntList: 3842 - 1 3843 - 4 3844 - 2 3845 - 3 3846 mergingIntList: 3847 - 4 3848 - 3 3849 `), 3850 Result: []byte(` 3851 mergingIntList: 3852 - 1 3853 - 4 3854 - 2 3855 - 3 3856 `), 3857 }, 3858 }, 3859 { 3860 Description: "delete an item in a int list and preserve order", 3861 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 3862 Original: []byte(` 3863 mergingIntList: 3864 - 1 3865 - 3 3866 - 2 3867 `), 3868 TwoWay: []byte(` 3869 $setElementOrder/mergingIntList: 3870 - 2 3871 - 1 3872 $deleteFromPrimitiveList/mergingIntList: 3873 - 3 3874 `), 3875 Modified: []byte(` 3876 mergingIntList: 3877 - 2 3878 - 1 3879 `), 3880 Current: []byte(` 3881 mergingIntList: 3882 - 1 3883 - 2 3884 - 3 3885 `), 3886 ThreeWay: []byte(` 3887 $setElementOrder/mergingIntList: 3888 - 2 3889 - 1 3890 $deleteFromPrimitiveList/mergingIntList: 3891 - 3 3892 `), 3893 Result: []byte(` 3894 mergingIntList: 3895 - 2 3896 - 1 3897 `), 3898 }, 3899 }, 3900 { 3901 Description: "add and delete an item in a int list and preserve order", 3902 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 3903 Original: []byte(` 3904 mergingIntList: 3905 - 1 3906 - 3 3907 - 2 3908 `), 3909 TwoWay: []byte(` 3910 $setElementOrder/mergingIntList: 3911 - 4 3912 - 2 3913 - 1 3914 mergingIntList: 3915 - 4 3916 $deleteFromPrimitiveList/mergingIntList: 3917 - 3 3918 `), 3919 Modified: []byte(` 3920 mergingIntList: 3921 - 4 3922 - 2 3923 - 1 3924 `), 3925 Current: []byte(` 3926 mergingIntList: 3927 - 1 3928 - 2 3929 - 3 3930 `), 3931 ThreeWay: []byte(` 3932 $setElementOrder/mergingIntList: 3933 - 4 3934 - 2 3935 - 1 3936 mergingIntList: 3937 - 4 3938 $deleteFromPrimitiveList/mergingIntList: 3939 - 3 3940 `), 3941 Result: []byte(` 3942 mergingIntList: 3943 - 4 3944 - 2 3945 - 1 3946 `), 3947 }, 3948 }, 3949 { 3950 Description: "set elements order in a int list", 3951 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 3952 Original: []byte(` 3953 mergingIntList: 3954 - 1 3955 - 3 3956 - 4 3957 - 2 3958 `), 3959 TwoWay: []byte(` 3960 $setElementOrder/mergingIntList: 3961 - 4 3962 - 2 3963 - 3 3964 - 1 3965 `), 3966 Modified: []byte(` 3967 mergingIntList: 3968 - 4 3969 - 2 3970 - 3 3971 - 1 3972 `), 3973 Current: []byte(` 3974 mergingIntList: 3975 - 1 3976 - 3 3977 - 4 3978 - 2 3979 `), 3980 ThreeWay: []byte(` 3981 $setElementOrder/mergingIntList: 3982 - 4 3983 - 2 3984 - 3 3985 - 1 3986 `), 3987 Result: []byte(` 3988 mergingIntList: 3989 - 4 3990 - 2 3991 - 3 3992 - 1 3993 `), 3994 }, 3995 }, 3996 { 3997 Description: "set elements order in a int list with server-only items", 3998 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 3999 Original: []byte(` 4000 mergingIntList: 4001 - 1 4002 - 3 4003 - 4 4004 - 2 4005 `), 4006 TwoWay: []byte(` 4007 $setElementOrder/mergingIntList: 4008 - 4 4009 - 2 4010 - 3 4011 - 1 4012 `), 4013 Modified: []byte(` 4014 mergingIntList: 4015 - 4 4016 - 2 4017 - 3 4018 - 1 4019 `), 4020 Current: []byte(` 4021 mergingIntList: 4022 - 1 4023 - 3 4024 - 4 4025 - 2 4026 - 9 4027 `), 4028 ThreeWay: []byte(` 4029 $setElementOrder/mergingIntList: 4030 - 4 4031 - 2 4032 - 3 4033 - 1 4034 `), 4035 Result: []byte(` 4036 mergingIntList: 4037 - 4 4038 - 2 4039 - 3 4040 - 1 4041 - 9 4042 `), 4043 }, 4044 }, 4045 { 4046 Description: "set elements order in a int list with server-only items 2", 4047 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 4048 Original: []byte(` 4049 mergingIntList: 4050 - 1 4051 - 2 4052 - 3 4053 - 4 4054 `), 4055 TwoWay: []byte(` 4056 $setElementOrder/mergingIntList: 4057 - 2 4058 - 1 4059 - 4 4060 - 3 4061 `), 4062 Modified: []byte(` 4063 mergingIntList: 4064 - 2 4065 - 1 4066 - 4 4067 - 3 4068 `), 4069 Current: []byte(` 4070 mergingIntList: 4071 - 1 4072 - 2 4073 - 9 4074 - 3 4075 - 4 4076 `), 4077 ThreeWay: []byte(` 4078 $setElementOrder/mergingIntList: 4079 - 2 4080 - 1 4081 - 4 4082 - 3 4083 `), 4084 Result: []byte(` 4085 mergingIntList: 4086 - 2 4087 - 1 4088 - 9 4089 - 4 4090 - 3 4091 `), 4092 }, 4093 }, 4094 { 4095 Description: "set elements order in a int list with server-only items 3", 4096 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 4097 Original: []byte(` 4098 mergingIntList: 4099 - 1 4100 - 2 4101 - 3 4102 - 4 4103 `), 4104 TwoWay: []byte(` 4105 $setElementOrder/mergingIntList: 4106 - 2 4107 - 1 4108 - 4 4109 - 3 4110 `), 4111 Modified: []byte(` 4112 mergingIntList: 4113 - 2 4114 - 1 4115 - 4 4116 - 3 4117 `), 4118 Current: []byte(` 4119 mergingIntList: 4120 - 1 4121 - 2 4122 - 7 4123 - 9 4124 - 8 4125 - 3 4126 - 4 4127 `), 4128 ThreeWay: []byte(` 4129 $setElementOrder/mergingIntList: 4130 - 2 4131 - 1 4132 - 4 4133 - 3 4134 `), 4135 Result: []byte(` 4136 mergingIntList: 4137 - 2 4138 - 1 4139 - 7 4140 - 9 4141 - 8 4142 - 4 4143 - 3 4144 `), 4145 }, 4146 }, 4147 { 4148 // This test case is used just to demonstrate the behavior when dealing with a list with duplicate 4149 Description: "behavior of set element order for a merging list with duplicate", 4150 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 4151 Original: []byte(` 4152 mergingList: 4153 - name: 1 4154 - name: 2 4155 value: dup1 4156 - name: 3 4157 - name: 2 4158 value: dup2 4159 - name: 4 4160 `), 4161 Current: []byte(` 4162 mergingList: 4163 - name: 1 4164 - name: 2 4165 value: dup1 4166 - name: 3 4167 - name: 2 4168 value: dup2 4169 - name: 4 4170 `), 4171 Modified: []byte(` 4172 mergingList: 4173 - name: 2 4174 value: dup1 4175 - name: 1 4176 - name: 4 4177 - name: 3 4178 - name: 2 4179 value: dup2 4180 `), 4181 TwoWay: []byte(` 4182 $setElementOrder/mergingList: 4183 - name: 2 4184 - name: 1 4185 - name: 4 4186 - name: 3 4187 - name: 2 4188 `), 4189 TwoWayResult: []byte(` 4190 mergingList: 4191 - name: 2 4192 value: dup1 4193 - name: 2 4194 value: dup2 4195 - name: 1 4196 - name: 4 4197 - name: 3 4198 `), 4199 ThreeWay: []byte(` 4200 $setElementOrder/mergingList: 4201 - name: 2 4202 - name: 1 4203 - name: 4 4204 - name: 3 4205 - name: 2 4206 `), 4207 Result: []byte(` 4208 mergingList: 4209 - name: 2 4210 value: dup1 4211 - name: 2 4212 value: dup2 4213 - name: 1 4214 - name: 4 4215 - name: 3 4216 `), 4217 }, 4218 }, 4219 { 4220 // This test case is used just to demonstrate the behavior when dealing with a list with duplicate 4221 Description: "behavior of set element order for a merging int list with duplicate", 4222 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 4223 Original: []byte(` 4224 mergingIntList: 4225 - 1 4226 - 2 4227 - 3 4228 - 2 4229 - 4 4230 `), 4231 Current: []byte(` 4232 mergingIntList: 4233 - 1 4234 - 2 4235 - 3 4236 - 2 4237 - 4 4238 `), 4239 Modified: []byte(` 4240 mergingIntList: 4241 - 2 4242 - 1 4243 - 4 4244 - 3 4245 - 2 4246 `), 4247 TwoWay: []byte(` 4248 $setElementOrder/mergingIntList: 4249 - 2 4250 - 1 4251 - 4 4252 - 3 4253 - 2 4254 `), 4255 TwoWayResult: []byte(` 4256 mergingIntList: 4257 - 2 4258 - 2 4259 - 1 4260 - 4 4261 - 3 4262 `), 4263 ThreeWay: []byte(` 4264 $setElementOrder/mergingIntList: 4265 - 2 4266 - 1 4267 - 4 4268 - 3 4269 - 2 4270 `), 4271 Result: []byte(` 4272 mergingIntList: 4273 - 2 4274 - 2 4275 - 1 4276 - 4 4277 - 3 4278 `), 4279 }, 4280 }, 4281 { 4282 Description: "retainKeys map should clear defaulted field", 4283 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 4284 Original: []byte(`{}`), 4285 Current: []byte(` 4286 retainKeysMap: 4287 value: foo 4288 `), 4289 Modified: []byte(` 4290 retainKeysMap: 4291 other: bar 4292 `), 4293 TwoWay: []byte(` 4294 retainKeysMap: 4295 other: bar 4296 `), 4297 ThreeWay: []byte(` 4298 retainKeysMap: 4299 $retainKeys: 4300 - other 4301 other: bar 4302 `), 4303 Result: []byte(` 4304 retainKeysMap: 4305 other: bar 4306 `), 4307 }, 4308 }, 4309 { 4310 Description: "retainKeys map should clear defaulted field with conflict (discriminated union)", 4311 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 4312 Original: []byte(`{}`), 4313 Current: []byte(` 4314 retainKeysMap: 4315 name: type1 4316 value: foo 4317 `), 4318 Modified: []byte(` 4319 retainKeysMap: 4320 name: type2 4321 other: bar 4322 `), 4323 TwoWay: []byte(` 4324 retainKeysMap: 4325 name: type2 4326 other: bar 4327 `), 4328 ThreeWay: []byte(` 4329 retainKeysMap: 4330 $retainKeys: 4331 - name 4332 - other 4333 name: type2 4334 other: bar 4335 `), 4336 Result: []byte(` 4337 retainKeysMap: 4338 name: type2 4339 other: bar 4340 `), 4341 }, 4342 }, 4343 { 4344 Description: "retainKeys map adds a field", 4345 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 4346 Original: []byte(` 4347 retainKeysMap: 4348 name: foo 4349 `), 4350 Current: []byte(` 4351 retainKeysMap: 4352 name: foo 4353 `), 4354 Modified: []byte(` 4355 retainKeysMap: 4356 name: foo 4357 value: bar 4358 `), 4359 TwoWay: []byte(` 4360 retainKeysMap: 4361 $retainKeys: 4362 - name 4363 - value 4364 value: bar 4365 `), 4366 ThreeWay: []byte(` 4367 retainKeysMap: 4368 $retainKeys: 4369 - name 4370 - value 4371 value: bar 4372 `), 4373 Result: []byte(` 4374 retainKeysMap: 4375 name: foo 4376 value: bar 4377 `), 4378 }, 4379 }, 4380 { 4381 Description: "retainKeys map adds a field and clear a field", 4382 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 4383 Original: []byte(` 4384 retainKeysMap: 4385 name: foo 4386 `), 4387 Current: []byte(` 4388 retainKeysMap: 4389 name: foo 4390 other: a 4391 `), 4392 Modified: []byte(` 4393 retainKeysMap: 4394 name: foo 4395 value: bar 4396 `), 4397 TwoWay: []byte(` 4398 retainKeysMap: 4399 $retainKeys: 4400 - name 4401 - value 4402 value: bar 4403 `), 4404 ThreeWay: []byte(` 4405 retainKeysMap: 4406 $retainKeys: 4407 - name 4408 - value 4409 value: bar 4410 `), 4411 Result: []byte(` 4412 retainKeysMap: 4413 name: foo 4414 value: bar 4415 `), 4416 }, 4417 }, 4418 { 4419 Description: "retainKeys map deletes a field", 4420 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 4421 Original: []byte(` 4422 retainKeysMap: 4423 name: foo 4424 value: bar 4425 `), 4426 Current: []byte(` 4427 retainKeysMap: 4428 name: foo 4429 value: bar 4430 `), 4431 Modified: []byte(` 4432 retainKeysMap: 4433 name: foo 4434 `), 4435 TwoWay: []byte(` 4436 retainKeysMap: 4437 $retainKeys: 4438 - name 4439 value: null 4440 `), 4441 ThreeWay: []byte(` 4442 retainKeysMap: 4443 $retainKeys: 4444 - name 4445 value: null 4446 `), 4447 Result: []byte(` 4448 retainKeysMap: 4449 name: foo 4450 `), 4451 }, 4452 }, 4453 { 4454 Description: "retainKeys map deletes a field and clears a field", 4455 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 4456 Original: []byte(` 4457 retainKeysMap: 4458 name: foo 4459 value: bar 4460 `), 4461 Current: []byte(` 4462 retainKeysMap: 4463 name: foo 4464 value: bar 4465 other: a 4466 `), 4467 Modified: []byte(` 4468 retainKeysMap: 4469 name: foo 4470 `), 4471 TwoWay: []byte(` 4472 retainKeysMap: 4473 $retainKeys: 4474 - name 4475 value: null 4476 `), 4477 ThreeWay: []byte(` 4478 retainKeysMap: 4479 $retainKeys: 4480 - name 4481 value: null 4482 `), 4483 Result: []byte(` 4484 retainKeysMap: 4485 name: foo 4486 `), 4487 }, 4488 }, 4489 { 4490 Description: "retainKeys map clears a field", 4491 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 4492 Original: []byte(` 4493 retainKeysMap: 4494 name: foo 4495 value: bar 4496 `), 4497 Current: []byte(` 4498 retainKeysMap: 4499 name: foo 4500 value: bar 4501 other: a 4502 `), 4503 Modified: []byte(` 4504 retainKeysMap: 4505 name: foo 4506 value: bar 4507 `), 4508 TwoWay: []byte(`{}`), 4509 ThreeWay: []byte(` 4510 retainKeysMap: 4511 $retainKeys: 4512 - name 4513 - value 4514 `), 4515 Result: []byte(` 4516 retainKeysMap: 4517 name: foo 4518 value: bar 4519 `), 4520 }, 4521 }, 4522 { 4523 Description: "retainKeys map nested map with no change", 4524 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 4525 Original: []byte(` 4526 retainKeysMap: 4527 name: foo 4528 simpleMap: 4529 key1: a 4530 `), 4531 Current: []byte(` 4532 retainKeysMap: 4533 name: foo 4534 simpleMap: 4535 key1: a 4536 `), 4537 Modified: []byte(` 4538 retainKeysMap: 4539 name: foo 4540 value: bar 4541 simpleMap: 4542 key1: a 4543 `), 4544 TwoWay: []byte(` 4545 retainKeysMap: 4546 $retainKeys: 4547 - name 4548 - simpleMap 4549 - value 4550 value: bar 4551 `), 4552 ThreeWay: []byte(` 4553 retainKeysMap: 4554 $retainKeys: 4555 - name 4556 - simpleMap 4557 - value 4558 value: bar 4559 `), 4560 Result: []byte(` 4561 retainKeysMap: 4562 name: foo 4563 value: bar 4564 simpleMap: 4565 key1: a 4566 `), 4567 }, 4568 }, 4569 { 4570 Description: "retainKeys map adds a field in a nested map", 4571 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 4572 Original: []byte(` 4573 retainKeysMap: 4574 name: foo 4575 value: bar 4576 simpleMap: 4577 key1: a 4578 `), 4579 Current: []byte(` 4580 retainKeysMap: 4581 name: foo 4582 value: bar 4583 simpleMap: 4584 key1: a 4585 key3: c 4586 `), 4587 Modified: []byte(` 4588 retainKeysMap: 4589 name: foo 4590 value: bar 4591 simpleMap: 4592 key1: a 4593 key2: b 4594 `), 4595 TwoWay: []byte(` 4596 retainKeysMap: 4597 $retainKeys: 4598 - name 4599 - simpleMap 4600 - value 4601 simpleMap: 4602 key2: b 4603 `), 4604 ThreeWay: []byte(` 4605 retainKeysMap: 4606 $retainKeys: 4607 - name 4608 - simpleMap 4609 - value 4610 simpleMap: 4611 key2: b 4612 `), 4613 Result: []byte(` 4614 retainKeysMap: 4615 name: foo 4616 value: bar 4617 simpleMap: 4618 key1: a 4619 key2: b 4620 key3: c 4621 `), 4622 }, 4623 }, 4624 { 4625 Description: "retainKeys map deletes a field in a nested map", 4626 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 4627 Original: []byte(` 4628 retainKeysMap: 4629 name: foo 4630 value: bar 4631 simpleMap: 4632 key1: a 4633 key2: b 4634 `), 4635 Current: []byte(` 4636 retainKeysMap: 4637 name: foo 4638 value: bar 4639 simpleMap: 4640 key1: a 4641 key2: b 4642 key3: c 4643 `), 4644 Modified: []byte(` 4645 retainKeysMap: 4646 name: foo 4647 value: bar 4648 simpleMap: 4649 key1: a 4650 `), 4651 TwoWay: []byte(` 4652 retainKeysMap: 4653 $retainKeys: 4654 - name 4655 - simpleMap 4656 - value 4657 simpleMap: 4658 key2: null 4659 `), 4660 ThreeWay: []byte(` 4661 retainKeysMap: 4662 $retainKeys: 4663 - name 4664 - simpleMap 4665 - value 4666 simpleMap: 4667 key2: null 4668 `), 4669 Result: []byte(` 4670 retainKeysMap: 4671 name: foo 4672 value: bar 4673 simpleMap: 4674 key1: a 4675 key3: c 4676 `), 4677 }, 4678 }, 4679 { 4680 Description: "retainKeys map changes a field in a nested map", 4681 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 4682 Original: []byte(` 4683 retainKeysMap: 4684 name: foo 4685 value: bar 4686 simpleMap: 4687 key1: a 4688 key2: b 4689 `), 4690 Current: []byte(` 4691 retainKeysMap: 4692 name: foo 4693 value: bar 4694 simpleMap: 4695 key1: a 4696 key2: b 4697 key3: c 4698 `), 4699 Modified: []byte(` 4700 retainKeysMap: 4701 name: foo 4702 value: bar 4703 simpleMap: 4704 key1: x 4705 key2: b 4706 `), 4707 TwoWay: []byte(` 4708 retainKeysMap: 4709 $retainKeys: 4710 - name 4711 - simpleMap 4712 - value 4713 simpleMap: 4714 key1: x 4715 `), 4716 ThreeWay: []byte(` 4717 retainKeysMap: 4718 $retainKeys: 4719 - name 4720 - simpleMap 4721 - value 4722 simpleMap: 4723 key1: x 4724 `), 4725 Result: []byte(` 4726 retainKeysMap: 4727 name: foo 4728 value: bar 4729 simpleMap: 4730 key1: x 4731 key2: b 4732 key3: c 4733 `), 4734 }, 4735 }, 4736 { 4737 Description: "retainKeys map changes a field in a nested map with conflict", 4738 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 4739 Original: []byte(` 4740 retainKeysMap: 4741 name: foo 4742 value: bar 4743 simpleMap: 4744 key1: old 4745 key2: b 4746 `), 4747 Current: []byte(` 4748 retainKeysMap: 4749 name: foo 4750 value: bar 4751 simpleMap: 4752 key1: new 4753 key2: b 4754 key3: c 4755 `), 4756 Modified: []byte(` 4757 retainKeysMap: 4758 name: foo 4759 value: bar 4760 simpleMap: 4761 key1: modified 4762 key2: b 4763 `), 4764 TwoWay: []byte(` 4765 retainKeysMap: 4766 $retainKeys: 4767 - name 4768 - simpleMap 4769 - value 4770 simpleMap: 4771 key1: modified 4772 `), 4773 ThreeWay: []byte(` 4774 retainKeysMap: 4775 $retainKeys: 4776 - name 4777 - simpleMap 4778 - value 4779 simpleMap: 4780 key1: modified 4781 `), 4782 Result: []byte(` 4783 retainKeysMap: 4784 name: foo 4785 value: bar 4786 simpleMap: 4787 key1: modified 4788 key2: b 4789 key3: c 4790 `), 4791 }, 4792 }, 4793 { 4794 Description: "retainKeys map replaces non-merging list", 4795 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 4796 Original: []byte(` 4797 retainKeysMap: 4798 name: foo 4799 value: bar 4800 nonMergingList: 4801 - name: a 4802 - name: b 4803 `), 4804 Current: []byte(` 4805 retainKeysMap: 4806 name: foo 4807 value: bar 4808 nonMergingList: 4809 - name: a 4810 - name: b 4811 `), 4812 Modified: []byte(` 4813 retainKeysMap: 4814 name: foo 4815 value: bar 4816 nonMergingList: 4817 - name: a 4818 - name: c 4819 - name: b 4820 `), 4821 TwoWay: []byte(` 4822 retainKeysMap: 4823 $retainKeys: 4824 - name 4825 - nonMergingList 4826 - value 4827 nonMergingList: 4828 - name: a 4829 - name: c 4830 - name: b 4831 `), 4832 ThreeWay: []byte(` 4833 retainKeysMap: 4834 $retainKeys: 4835 - name 4836 - nonMergingList 4837 - value 4838 nonMergingList: 4839 - name: a 4840 - name: c 4841 - name: b 4842 `), 4843 Result: []byte(` 4844 retainKeysMap: 4845 name: foo 4846 value: bar 4847 nonMergingList: 4848 - name: a 4849 - name: c 4850 - name: b 4851 `), 4852 }, 4853 }, 4854 { 4855 Description: "retainKeys map nested non-merging list with no change", 4856 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 4857 Original: []byte(` 4858 retainKeysMap: 4859 name: foo 4860 nonMergingList: 4861 - name: a 4862 - name: b 4863 `), 4864 Current: []byte(` 4865 retainKeysMap: 4866 name: foo 4867 nonMergingList: 4868 - name: a 4869 - name: b 4870 `), 4871 Modified: []byte(` 4872 retainKeysMap: 4873 name: foo 4874 value: bar 4875 nonMergingList: 4876 - name: a 4877 - name: b 4878 `), 4879 TwoWay: []byte(` 4880 retainKeysMap: 4881 $retainKeys: 4882 - name 4883 - nonMergingList 4884 - value 4885 value: bar 4886 `), 4887 ThreeWay: []byte(` 4888 retainKeysMap: 4889 $retainKeys: 4890 - name 4891 - nonMergingList 4892 - value 4893 value: bar 4894 `), 4895 Result: []byte(` 4896 retainKeysMap: 4897 name: foo 4898 value: bar 4899 nonMergingList: 4900 - name: a 4901 - name: b 4902 `), 4903 }, 4904 }, 4905 { 4906 Description: "retainKeys map nested non-merging list with no change with conflict", 4907 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 4908 Original: []byte(` 4909 retainKeysMap: 4910 name: foo 4911 nonMergingList: 4912 - name: a 4913 - name: b 4914 `), 4915 Current: []byte(` 4916 retainKeysMap: 4917 name: foo 4918 nonMergingList: 4919 - name: a 4920 - name: b 4921 - name: c 4922 `), 4923 Modified: []byte(` 4924 retainKeysMap: 4925 name: foo 4926 value: bar 4927 nonMergingList: 4928 - name: a 4929 - name: b 4930 `), 4931 TwoWay: []byte(` 4932 retainKeysMap: 4933 $retainKeys: 4934 - name 4935 - nonMergingList 4936 - value 4937 value: bar 4938 `), 4939 ThreeWay: []byte(` 4940 retainKeysMap: 4941 $retainKeys: 4942 - name 4943 - nonMergingList 4944 - value 4945 value: bar 4946 nonMergingList: 4947 - name: a 4948 - name: b 4949 `), 4950 Result: []byte(` 4951 retainKeysMap: 4952 name: foo 4953 value: bar 4954 nonMergingList: 4955 - name: a 4956 - name: b 4957 `), 4958 }, 4959 }, 4960 { 4961 Description: "retainKeys map deletes nested non-merging list", 4962 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 4963 Original: []byte(` 4964 retainKeysMap: 4965 name: foo 4966 nonMergingList: 4967 - name: a 4968 - name: b 4969 `), 4970 Current: []byte(` 4971 retainKeysMap: 4972 name: foo 4973 nonMergingList: 4974 - name: a 4975 - name: b 4976 `), 4977 Modified: []byte(` 4978 retainKeysMap: 4979 name: foo 4980 value: bar 4981 `), 4982 TwoWay: []byte(` 4983 retainKeysMap: 4984 $retainKeys: 4985 - name 4986 - value 4987 value: bar 4988 nonMergingList: null 4989 `), 4990 ThreeWay: []byte(` 4991 retainKeysMap: 4992 $retainKeys: 4993 - name 4994 - value 4995 value: bar 4996 nonMergingList: null 4997 `), 4998 Result: []byte(` 4999 retainKeysMap: 5000 name: foo 5001 value: bar 5002 `), 5003 }, 5004 }, 5005 { 5006 Description: "retainKeys map delete nested non-merging list with conflict", 5007 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 5008 Original: []byte(` 5009 retainKeysMap: 5010 name: foo 5011 nonMergingList: 5012 - name: a 5013 - name: b 5014 `), 5015 Current: []byte(` 5016 retainKeysMap: 5017 name: foo 5018 nonMergingList: 5019 - name: a 5020 - name: b 5021 - name: c 5022 `), 5023 Modified: []byte(` 5024 retainKeysMap: 5025 name: foo 5026 value: bar 5027 `), 5028 TwoWay: []byte(` 5029 retainKeysMap: 5030 $retainKeys: 5031 - name 5032 - value 5033 value: bar 5034 nonMergingList: null 5035 `), 5036 ThreeWay: []byte(` 5037 retainKeysMap: 5038 $retainKeys: 5039 - name 5040 - value 5041 value: bar 5042 nonMergingList: null 5043 `), 5044 Result: []byte(` 5045 retainKeysMap: 5046 name: foo 5047 value: bar 5048 `), 5049 }, 5050 }, 5051 { 5052 Description: "retainKeys map nested merging int list with no change", 5053 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 5054 Original: []byte(` 5055 retainKeysMap: 5056 name: foo 5057 mergingIntList: 5058 - 1 5059 - 2 5060 `), 5061 Current: []byte(` 5062 retainKeysMap: 5063 name: foo 5064 mergingIntList: 5065 - 1 5066 - 2 5067 - 3 5068 `), 5069 Modified: []byte(` 5070 retainKeysMap: 5071 name: foo 5072 value: bar 5073 mergingIntList: 5074 - 1 5075 - 2 5076 `), 5077 TwoWay: []byte(` 5078 retainKeysMap: 5079 $retainKeys: 5080 - mergingIntList 5081 - name 5082 - value 5083 value: bar 5084 `), 5085 ThreeWay: []byte(` 5086 retainKeysMap: 5087 $retainKeys: 5088 - mergingIntList 5089 - name 5090 - value 5091 $setElementOrder/mergingIntList: 5092 - 1 5093 - 2 5094 value: bar 5095 `), 5096 Result: []byte(` 5097 retainKeysMap: 5098 name: foo 5099 value: bar 5100 mergingIntList: 5101 - 1 5102 - 2 5103 - 3 5104 `), 5105 }, 5106 }, 5107 { 5108 Description: "retainKeys map adds an item in nested merging int list", 5109 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 5110 Original: []byte(` 5111 retainKeysMap: 5112 name: foo 5113 mergingIntList: 5114 - 1 5115 - 2 5116 `), 5117 Current: []byte(` 5118 retainKeysMap: 5119 name: foo 5120 mergingIntList: 5121 - 1 5122 - 2 5123 - 3 5124 `), 5125 Modified: []byte(` 5126 retainKeysMap: 5127 name: foo 5128 mergingIntList: 5129 - 1 5130 - 2 5131 - 4 5132 `), 5133 TwoWay: []byte(` 5134 retainKeysMap: 5135 $setElementOrder/mergingIntList: 5136 - 1 5137 - 2 5138 - 4 5139 $retainKeys: 5140 - mergingIntList 5141 - name 5142 mergingIntList: 5143 - 4 5144 `), 5145 ThreeWay: []byte(` 5146 retainKeysMap: 5147 $setElementOrder/mergingIntList: 5148 - 1 5149 - 2 5150 - 4 5151 $retainKeys: 5152 - mergingIntList 5153 - name 5154 mergingIntList: 5155 - 4 5156 `), 5157 Result: []byte(` 5158 retainKeysMap: 5159 name: foo 5160 mergingIntList: 5161 - 1 5162 - 2 5163 - 4 5164 - 3 5165 `), 5166 }, 5167 }, 5168 { 5169 Description: "retainKeys map deletes an item in nested merging int list", 5170 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 5171 Original: []byte(` 5172 retainKeysMap: 5173 name: foo 5174 mergingIntList: 5175 - 1 5176 - 2 5177 - 3 5178 `), 5179 Current: []byte(` 5180 retainKeysMap: 5181 name: foo 5182 mergingIntList: 5183 - 1 5184 - 2 5185 - 3 5186 - 4 5187 `), 5188 Modified: []byte(` 5189 retainKeysMap: 5190 name: foo 5191 mergingIntList: 5192 - 1 5193 - 3 5194 `), 5195 TwoWay: []byte(` 5196 retainKeysMap: 5197 $retainKeys: 5198 - mergingIntList 5199 - name 5200 $deleteFromPrimitiveList/mergingIntList: 5201 - 2 5202 $setElementOrder/mergingIntList: 5203 - 1 5204 - 3 5205 `), 5206 ThreeWay: []byte(` 5207 retainKeysMap: 5208 $retainKeys: 5209 - mergingIntList 5210 - name 5211 $deleteFromPrimitiveList/mergingIntList: 5212 - 2 5213 $setElementOrder/mergingIntList: 5214 - 1 5215 - 3 5216 `), 5217 Result: []byte(` 5218 retainKeysMap: 5219 name: foo 5220 mergingIntList: 5221 - 1 5222 - 3 5223 - 4 5224 `), 5225 }, 5226 }, 5227 { 5228 Description: "retainKeys map adds an item and deletes an item in nested merging int list", 5229 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 5230 Original: []byte(` 5231 retainKeysMap: 5232 name: foo 5233 mergingIntList: 5234 - 1 5235 - 2 5236 - 3 5237 `), 5238 Current: []byte(` 5239 retainKeysMap: 5240 name: foo 5241 mergingIntList: 5242 - 1 5243 - 2 5244 - 3 5245 - 4 5246 `), 5247 Modified: []byte(` 5248 retainKeysMap: 5249 name: foo 5250 mergingIntList: 5251 - 1 5252 - 3 5253 - 5 5254 `), 5255 TwoWay: []byte(` 5256 retainKeysMap: 5257 $retainKeys: 5258 - mergingIntList 5259 - name 5260 mergingIntList: 5261 - 5 5262 $deleteFromPrimitiveList/mergingIntList: 5263 - 2 5264 $setElementOrder/mergingIntList: 5265 - 1 5266 - 3 5267 - 5 5268 `), 5269 ThreeWay: []byte(` 5270 retainKeysMap: 5271 $retainKeys: 5272 - mergingIntList 5273 - name 5274 mergingIntList: 5275 - 5 5276 $deleteFromPrimitiveList/mergingIntList: 5277 - 2 5278 $setElementOrder/mergingIntList: 5279 - 1 5280 - 3 5281 - 5 5282 `), 5283 Result: []byte(` 5284 retainKeysMap: 5285 name: foo 5286 mergingIntList: 5287 - 1 5288 - 3 5289 - 5 5290 - 4 5291 `), 5292 }, 5293 }, 5294 { 5295 Description: "retainKeys map deletes nested merging int list", 5296 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 5297 Original: []byte(` 5298 retainKeysMap: 5299 name: foo 5300 mergingIntList: 5301 - 1 5302 - 2 5303 - 3 5304 `), 5305 Current: []byte(` 5306 retainKeysMap: 5307 name: foo 5308 mergingIntList: 5309 - 1 5310 - 2 5311 - 3 5312 `), 5313 Modified: []byte(` 5314 retainKeysMap: 5315 name: foo 5316 `), 5317 TwoWay: []byte(` 5318 retainKeysMap: 5319 $retainKeys: 5320 - name 5321 mergingIntList: null 5322 `), 5323 ThreeWay: []byte(` 5324 retainKeysMap: 5325 $retainKeys: 5326 - name 5327 mergingIntList: null 5328 `), 5329 Result: []byte(` 5330 retainKeysMap: 5331 name: foo 5332 `), 5333 }, 5334 }, 5335 { 5336 Description: "retainKeys map nested merging list with no change", 5337 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 5338 Original: []byte(` 5339 retainKeysMap: 5340 name: foo 5341 mergingList: 5342 - name: a 5343 - name: b 5344 `), 5345 Current: []byte(` 5346 retainKeysMap: 5347 name: foo 5348 mergingList: 5349 - name: a 5350 - name: b 5351 - name: c 5352 `), 5353 Modified: []byte(` 5354 retainKeysMap: 5355 name: foo 5356 value: bar 5357 mergingList: 5358 - name: a 5359 - name: b 5360 `), 5361 TwoWay: []byte(` 5362 retainKeysMap: 5363 $retainKeys: 5364 - mergingList 5365 - name 5366 - value 5367 value: bar 5368 `), 5369 ThreeWay: []byte(` 5370 retainKeysMap: 5371 $retainKeys: 5372 - mergingList 5373 - name 5374 - value 5375 $setElementOrder/mergingList: 5376 - name: a 5377 - name: b 5378 value: bar 5379 `), 5380 Result: []byte(` 5381 retainKeysMap: 5382 name: foo 5383 value: bar 5384 mergingList: 5385 - name: a 5386 - name: b 5387 - name: c 5388 `), 5389 }, 5390 }, 5391 { 5392 Description: "retainKeys map adds an item in nested merging list", 5393 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 5394 Original: []byte(` 5395 retainKeysMap: 5396 name: foo 5397 mergingList: 5398 - name: a 5399 - name: b 5400 `), 5401 Current: []byte(` 5402 retainKeysMap: 5403 name: foo 5404 mergingList: 5405 - name: a 5406 - name: b 5407 - name: x 5408 `), 5409 Modified: []byte(` 5410 retainKeysMap: 5411 name: foo 5412 mergingList: 5413 - name: a 5414 - name: b 5415 - name: c 5416 `), 5417 TwoWay: []byte(` 5418 retainKeysMap: 5419 $retainKeys: 5420 - mergingList 5421 - name 5422 $setElementOrder/mergingList: 5423 - name: a 5424 - name: b 5425 - name: c 5426 mergingList: 5427 - name: c 5428 `), 5429 ThreeWay: []byte(` 5430 retainKeysMap: 5431 $retainKeys: 5432 - mergingList 5433 - name 5434 $setElementOrder/mergingList: 5435 - name: a 5436 - name: b 5437 - name: c 5438 mergingList: 5439 - name: c 5440 `), 5441 Result: []byte(` 5442 retainKeysMap: 5443 name: foo 5444 mergingList: 5445 - name: a 5446 - name: b 5447 - name: c 5448 - name: x 5449 `), 5450 }, 5451 }, 5452 { 5453 Description: "retainKeys map changes an item in nested merging list", 5454 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 5455 Original: []byte(` 5456 retainKeysMap: 5457 name: foo 5458 mergingList: 5459 - name: a 5460 - name: b 5461 value: foo 5462 `), 5463 Current: []byte(` 5464 retainKeysMap: 5465 name: foo 5466 mergingList: 5467 - name: a 5468 - name: b 5469 value: foo 5470 - name: x 5471 `), 5472 Modified: []byte(` 5473 retainKeysMap: 5474 name: foo 5475 mergingList: 5476 - name: a 5477 - name: b 5478 value: bar 5479 `), 5480 TwoWay: []byte(` 5481 retainKeysMap: 5482 $retainKeys: 5483 - mergingList 5484 - name 5485 $setElementOrder/mergingList: 5486 - name: a 5487 - name: b 5488 mergingList: 5489 - name: b 5490 value: bar 5491 `), 5492 ThreeWay: []byte(` 5493 retainKeysMap: 5494 $retainKeys: 5495 - mergingList 5496 - name 5497 $setElementOrder/mergingList: 5498 - name: a 5499 - name: b 5500 mergingList: 5501 - name: b 5502 value: bar 5503 `), 5504 Result: []byte(` 5505 retainKeysMap: 5506 name: foo 5507 mergingList: 5508 - name: a 5509 - name: b 5510 value: bar 5511 - name: x 5512 `), 5513 }, 5514 }, 5515 { 5516 Description: "retainKeys map deletes nested merging list", 5517 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 5518 Original: []byte(` 5519 retainKeysMap: 5520 name: foo 5521 mergingList: 5522 - name: a 5523 - name: b 5524 `), 5525 Current: []byte(` 5526 retainKeysMap: 5527 name: foo 5528 mergingList: 5529 - name: a 5530 - name: b 5531 `), 5532 Modified: []byte(` 5533 retainKeysMap: 5534 name: foo 5535 value: bar 5536 `), 5537 TwoWay: []byte(` 5538 retainKeysMap: 5539 $retainKeys: 5540 - name 5541 - value 5542 value: bar 5543 mergingList: null 5544 `), 5545 ThreeWay: []byte(` 5546 retainKeysMap: 5547 $retainKeys: 5548 - name 5549 - value 5550 value: bar 5551 mergingList: null 5552 `), 5553 Result: []byte(` 5554 retainKeysMap: 5555 name: foo 5556 value: bar 5557 `), 5558 }, 5559 }, 5560 { 5561 Description: "retainKeys map deletes an item in nested merging list", 5562 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 5563 Original: []byte(` 5564 retainKeysMap: 5565 name: foo 5566 mergingList: 5567 - name: a 5568 - name: b 5569 `), 5570 Current: []byte(` 5571 retainKeysMap: 5572 name: foo 5573 mergingList: 5574 - name: a 5575 - name: b 5576 - name: x 5577 `), 5578 Modified: []byte(` 5579 retainKeysMap: 5580 name: foo 5581 mergingList: 5582 - name: a 5583 `), 5584 TwoWay: []byte(` 5585 retainKeysMap: 5586 $retainKeys: 5587 - mergingList 5588 - name 5589 $setElementOrder/mergingList: 5590 - name: a 5591 mergingList: 5592 - name: b 5593 $patch: delete 5594 `), 5595 ThreeWay: []byte(` 5596 retainKeysMap: 5597 $retainKeys: 5598 - mergingList 5599 - name 5600 $setElementOrder/mergingList: 5601 - name: a 5602 mergingList: 5603 - name: b 5604 $patch: delete 5605 `), 5606 Result: []byte(` 5607 retainKeysMap: 5608 name: foo 5609 mergingList: 5610 - name: a 5611 - name: x 5612 `), 5613 }, 5614 }, 5615 { 5616 Description: "retainKeys list of maps clears a field", 5617 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 5618 Original: []byte(` 5619 retainKeysMergingList: 5620 - name: bar 5621 - name: foo 5622 value: a 5623 `), 5624 Current: []byte(` 5625 retainKeysMergingList: 5626 - name: bar 5627 - name: foo 5628 value: a 5629 other: x 5630 `), 5631 Modified: []byte(` 5632 retainKeysMergingList: 5633 - name: bar 5634 - name: foo 5635 value: a 5636 `), 5637 TwoWay: []byte(`{}`), 5638 ThreeWay: []byte(` 5639 $setElementOrder/retainKeysMergingList: 5640 - name: bar 5641 - name: foo 5642 retainKeysMergingList: 5643 - $retainKeys: 5644 - name 5645 - value 5646 name: foo 5647 `), 5648 Result: []byte(` 5649 retainKeysMergingList: 5650 - name: bar 5651 - name: foo 5652 value: a 5653 `), 5654 }, 5655 }, 5656 { 5657 Description: "retainKeys list of maps clears a field with conflict", 5658 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 5659 Original: []byte(` 5660 retainKeysMergingList: 5661 - name: bar 5662 - name: foo 5663 value: old 5664 `), 5665 Current: []byte(` 5666 retainKeysMergingList: 5667 - name: bar 5668 - name: foo 5669 value: new 5670 other: x 5671 `), 5672 Modified: []byte(` 5673 retainKeysMergingList: 5674 - name: bar 5675 - name: foo 5676 value: modified 5677 `), 5678 TwoWay: []byte(` 5679 $setElementOrder/retainKeysMergingList: 5680 - name: bar 5681 - name: foo 5682 retainKeysMergingList: 5683 - $retainKeys: 5684 - name 5685 - value 5686 name: foo 5687 value: modified 5688 `), 5689 ThreeWay: []byte(` 5690 $setElementOrder/retainKeysMergingList: 5691 - name: bar 5692 - name: foo 5693 retainKeysMergingList: 5694 - $retainKeys: 5695 - name 5696 - value 5697 name: foo 5698 value: modified 5699 `), 5700 Result: []byte(` 5701 retainKeysMergingList: 5702 - name: bar 5703 - name: foo 5704 value: modified 5705 `), 5706 }, 5707 }, 5708 { 5709 Description: "retainKeys list of maps changes a field and clear a field", 5710 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 5711 Original: []byte(` 5712 retainKeysMergingList: 5713 - name: bar 5714 - name: foo 5715 value: old 5716 `), 5717 Current: []byte(` 5718 retainKeysMergingList: 5719 - name: bar 5720 - name: foo 5721 value: old 5722 other: x 5723 `), 5724 Modified: []byte(` 5725 retainKeysMergingList: 5726 - name: bar 5727 - name: foo 5728 value: new 5729 `), 5730 TwoWay: []byte(` 5731 $setElementOrder/retainKeysMergingList: 5732 - name: bar 5733 - name: foo 5734 retainKeysMergingList: 5735 - $retainKeys: 5736 - name 5737 - value 5738 name: foo 5739 value: new 5740 `), 5741 ThreeWay: []byte(` 5742 $setElementOrder/retainKeysMergingList: 5743 - name: bar 5744 - name: foo 5745 retainKeysMergingList: 5746 - $retainKeys: 5747 - name 5748 - value 5749 name: foo 5750 value: new 5751 `), 5752 Result: []byte(` 5753 retainKeysMergingList: 5754 - name: bar 5755 - name: foo 5756 value: new 5757 `), 5758 }, 5759 }, 5760 { 5761 Description: "retainKeys list of maps changes a field and clear a field with conflict", 5762 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 5763 Original: []byte(` 5764 retainKeysMergingList: 5765 - name: bar 5766 - name: foo 5767 value: old 5768 `), 5769 Current: []byte(` 5770 retainKeysMergingList: 5771 - name: bar 5772 - name: foo 5773 value: modified 5774 other: x 5775 `), 5776 Modified: []byte(` 5777 retainKeysMergingList: 5778 - name: bar 5779 - name: foo 5780 value: new 5781 `), 5782 TwoWay: []byte(` 5783 $setElementOrder/retainKeysMergingList: 5784 - name: bar 5785 - name: foo 5786 retainKeysMergingList: 5787 - $retainKeys: 5788 - name 5789 - value 5790 name: foo 5791 value: new 5792 `), 5793 ThreeWay: []byte(` 5794 $setElementOrder/retainKeysMergingList: 5795 - name: bar 5796 - name: foo 5797 retainKeysMergingList: 5798 - $retainKeys: 5799 - name 5800 - value 5801 name: foo 5802 value: new 5803 `), 5804 Result: []byte(` 5805 retainKeysMergingList: 5806 - name: bar 5807 - name: foo 5808 value: new 5809 `), 5810 }, 5811 }, 5812 { 5813 Description: "retainKeys list of maps adds a field", 5814 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 5815 Original: []byte(` 5816 retainKeysMergingList: 5817 - name: bar 5818 - name: foo 5819 `), 5820 Current: []byte(` 5821 retainKeysMergingList: 5822 - name: bar 5823 - name: foo 5824 `), 5825 Modified: []byte(` 5826 retainKeysMergingList: 5827 - name: bar 5828 - name: foo 5829 value: a 5830 `), 5831 TwoWay: []byte(` 5832 $setElementOrder/retainKeysMergingList: 5833 - name: bar 5834 - name: foo 5835 retainKeysMergingList: 5836 - $retainKeys: 5837 - name 5838 - value 5839 name: foo 5840 value: a 5841 `), 5842 ThreeWay: []byte(` 5843 $setElementOrder/retainKeysMergingList: 5844 - name: bar 5845 - name: foo 5846 retainKeysMergingList: 5847 - $retainKeys: 5848 - name 5849 - value 5850 name: foo 5851 value: a 5852 `), 5853 Result: []byte(` 5854 retainKeysMergingList: 5855 - name: bar 5856 - name: foo 5857 value: a 5858 `), 5859 }, 5860 }, 5861 { 5862 Description: "retainKeys list of maps adds a field and clear a field", 5863 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 5864 Original: []byte(` 5865 retainKeysMergingList: 5866 - name: bar 5867 - name: foo 5868 `), 5869 Current: []byte(` 5870 retainKeysMergingList: 5871 - name: bar 5872 - name: foo 5873 other: x 5874 `), 5875 Modified: []byte(` 5876 retainKeysMergingList: 5877 - name: bar 5878 - name: foo 5879 value: a 5880 `), 5881 TwoWay: []byte(` 5882 $setElementOrder/retainKeysMergingList: 5883 - name: bar 5884 - name: foo 5885 retainKeysMergingList: 5886 - $retainKeys: 5887 - name 5888 - value 5889 name: foo 5890 value: a 5891 `), 5892 ThreeWay: []byte(` 5893 $setElementOrder/retainKeysMergingList: 5894 - name: bar 5895 - name: foo 5896 retainKeysMergingList: 5897 - $retainKeys: 5898 - name 5899 - value 5900 name: foo 5901 value: a 5902 `), 5903 Result: []byte(` 5904 retainKeysMergingList: 5905 - name: bar 5906 - name: foo 5907 value: a 5908 `), 5909 }, 5910 }, 5911 { 5912 Description: "retainKeys list of maps deletes a field", 5913 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 5914 Original: []byte(` 5915 retainKeysMergingList: 5916 - name: bar 5917 - name: foo 5918 value: a 5919 `), 5920 Current: []byte(` 5921 retainKeysMergingList: 5922 - name: bar 5923 - name: foo 5924 value: a 5925 `), 5926 Modified: []byte(` 5927 retainKeysMergingList: 5928 - name: bar 5929 - name: foo 5930 `), 5931 TwoWay: []byte(` 5932 $setElementOrder/retainKeysMergingList: 5933 - name: bar 5934 - name: foo 5935 retainKeysMergingList: 5936 - $retainKeys: 5937 - name 5938 name: foo 5939 value: null 5940 `), 5941 ThreeWay: []byte(` 5942 $setElementOrder/retainKeysMergingList: 5943 - name: bar 5944 - name: foo 5945 retainKeysMergingList: 5946 - $retainKeys: 5947 - name 5948 name: foo 5949 value: null 5950 `), 5951 Result: []byte(` 5952 retainKeysMergingList: 5953 - name: bar 5954 - name: foo 5955 `), 5956 }, 5957 }, 5958 { 5959 Description: "retainKeys list of maps deletes a field and clear a field", 5960 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 5961 Original: []byte(` 5962 retainKeysMergingList: 5963 - name: bar 5964 - name: foo 5965 value: a 5966 `), 5967 Current: []byte(` 5968 retainKeysMergingList: 5969 - name: bar 5970 - name: foo 5971 value: a 5972 other: x 5973 `), 5974 Modified: []byte(` 5975 retainKeysMergingList: 5976 - name: bar 5977 - name: foo 5978 `), 5979 TwoWay: []byte(` 5980 $setElementOrder/retainKeysMergingList: 5981 - name: bar 5982 - name: foo 5983 retainKeysMergingList: 5984 - $retainKeys: 5985 - name 5986 name: foo 5987 value: null 5988 `), 5989 ThreeWay: []byte(` 5990 $setElementOrder/retainKeysMergingList: 5991 - name: bar 5992 - name: foo 5993 retainKeysMergingList: 5994 - $retainKeys: 5995 - name 5996 name: foo 5997 value: null 5998 `), 5999 Result: []byte(` 6000 retainKeysMergingList: 6001 - name: bar 6002 - name: foo 6003 `), 6004 }, 6005 }, 6006 { 6007 Description: "delete and reorder in one list, reorder in another", 6008 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 6009 Original: []byte(` 6010 mergingList: 6011 - name: a 6012 value: a 6013 - name: b 6014 value: b 6015 mergeItemPtr: 6016 - name: c 6017 value: c 6018 - name: d 6019 value: d 6020 `), 6021 Current: []byte(` 6022 mergingList: 6023 - name: a 6024 value: a 6025 - name: b 6026 value: b 6027 mergeItemPtr: 6028 - name: c 6029 value: c 6030 - name: d 6031 value: d 6032 `), 6033 Modified: []byte(` 6034 mergingList: 6035 - name: b 6036 value: b 6037 mergeItemPtr: 6038 - name: d 6039 value: d 6040 - name: c 6041 value: c 6042 `), 6043 TwoWay: []byte(` 6044 $setElementOrder/mergingList: 6045 - name: b 6046 $setElementOrder/mergeItemPtr: 6047 - name: d 6048 - name: c 6049 mergingList: 6050 - $patch: delete 6051 name: a 6052 `), 6053 ThreeWay: []byte(` 6054 $setElementOrder/mergingList: 6055 - name: b 6056 $setElementOrder/mergeItemPtr: 6057 - name: d 6058 - name: c 6059 mergingList: 6060 - $patch: delete 6061 name: a 6062 `), 6063 Result: []byte(` 6064 mergingList: 6065 - name: b 6066 value: b 6067 mergeItemPtr: 6068 - name: d 6069 value: d 6070 - name: c 6071 value: c 6072 `), 6073 }, 6074 }, 6075 } 6076 6077 func TestStrategicMergePatch(t *testing.T) { 6078 testStrategicMergePatchWithCustomArgumentsUsingStruct(t, "bad struct", 6079 "{}", "{}", []byte("<THIS IS NOT A STRUCT>"), mergepatch.ErrBadArgKind(struct{}{}, []byte{})) 6080 6081 mergeItemOpenapiSchema := PatchMetaFromOpenAPI{ 6082 Schema: sptest.GetSchemaOrDie(&fakeMergeItemSchema, "mergeItem"), 6083 } 6084 schemas := []LookupPatchMeta{ 6085 mergeItemStructSchema, 6086 mergeItemOpenapiSchema, 6087 } 6088 6089 tc := StrategicMergePatchTestCases{} 6090 err := yaml.Unmarshal(createStrategicMergePatchTestCaseData, &tc) 6091 if err != nil { 6092 t.Errorf("can't unmarshal test cases: %s\n", err) 6093 return 6094 } 6095 6096 for _, schema := range schemas { 6097 testStrategicMergePatchWithCustomArguments(t, "bad original", 6098 "<THIS IS NOT JSON>", "{}", schema, mergepatch.ErrBadJSONDoc) 6099 testStrategicMergePatchWithCustomArguments(t, "bad patch", 6100 "{}", "<THIS IS NOT JSON>", schema, mergepatch.ErrBadJSONDoc) 6101 testStrategicMergePatchWithCustomArguments(t, "nil struct", 6102 "{}", "{}", nil, mergepatch.ErrBadArgKind(struct{}{}, nil)) 6103 6104 for _, c := range tc.TestCases { 6105 testTwoWayPatch(t, c, schema) 6106 testThreeWayPatch(t, c, schema) 6107 } 6108 6109 // run multiple times to exercise different map traversal orders 6110 for i := 0; i < 10; i++ { 6111 for _, c := range strategicMergePatchRawTestCases { 6112 testTwoWayPatchForRawTestCase(t, c, schema) 6113 testThreeWayPatchForRawTestCase(t, c, schema) 6114 } 6115 } 6116 } 6117 } 6118 6119 func testStrategicMergePatchWithCustomArgumentsUsingStruct(t *testing.T, description, original, patch string, dataStruct interface{}, expected error) { 6120 schema, actual := NewPatchMetaFromStruct(dataStruct) 6121 // If actual is not nil, check error. If errors match, return. 6122 if actual != nil { 6123 checkErrorsEqual(t, description, expected, actual, schema) 6124 return 6125 } 6126 testStrategicMergePatchWithCustomArguments(t, description, original, patch, schema, expected) 6127 } 6128 6129 func testStrategicMergePatchWithCustomArguments(t *testing.T, description, original, patch string, schema LookupPatchMeta, expected error) { 6130 _, actual := StrategicMergePatch([]byte(original), []byte(patch), schema) 6131 checkErrorsEqual(t, description, expected, actual, schema) 6132 } 6133 6134 func checkErrorsEqual(t *testing.T, description string, expected, actual error, schema LookupPatchMeta) { 6135 if actual != expected { 6136 if actual == nil { 6137 t.Errorf("using %s expected error: %s\ndid not occur in test case: %s", getSchemaType(schema), expected, description) 6138 return 6139 } 6140 6141 if expected == nil || actual.Error() != expected.Error() { 6142 t.Errorf("using %s unexpected error: %s\noccurred in test case: %s", getSchemaType(schema), actual, description) 6143 return 6144 } 6145 } 6146 } 6147 6148 func testTwoWayPatch(t *testing.T, c StrategicMergePatchTestCase, schema LookupPatchMeta) { 6149 original, expectedPatch, modified, expectedResult := twoWayTestCaseToJSONOrFail(t, c, schema) 6150 6151 actualPatch, err := CreateTwoWayMergePatchUsingLookupPatchMeta(original, modified, schema) 6152 if err != nil { 6153 t.Errorf("using %s error: %s\nin test case: %s\ncannot create two way patch: %s:\n%s\n", 6154 getSchemaType(schema), err, c.Description, original, mergepatch.ToYAMLOrError(c.StrategicMergePatchTestCaseData)) 6155 return 6156 } 6157 6158 testPatchCreation(t, expectedPatch, actualPatch, c.Description) 6159 testPatchApplication(t, original, actualPatch, expectedResult, c.Description, "", schema) 6160 } 6161 6162 func testTwoWayPatchForRawTestCase(t *testing.T, c StrategicMergePatchRawTestCase, schema LookupPatchMeta) { 6163 original, expectedPatch, modified, expectedResult := twoWayRawTestCaseToJSONOrFail(t, c) 6164 6165 actualPatch, err := CreateTwoWayMergePatchUsingLookupPatchMeta(original, modified, schema) 6166 if err != nil { 6167 t.Errorf("error: %s\nin test case: %s\ncannot create two way patch:\noriginal:%s\ntwoWay:%s\nmodified:%s\ncurrent:%s\nthreeWay:%s\nresult:%s\n", 6168 err, c.Description, c.Original, c.TwoWay, c.Modified, c.Current, c.ThreeWay, c.Result) 6169 return 6170 } 6171 6172 testPatchCreation(t, expectedPatch, actualPatch, c.Description) 6173 testPatchApplication(t, original, actualPatch, expectedResult, c.Description, c.ExpectedError, schema) 6174 } 6175 6176 func twoWayTestCaseToJSONOrFail(t *testing.T, c StrategicMergePatchTestCase, schema LookupPatchMeta) ([]byte, []byte, []byte, []byte) { 6177 expectedResult := c.TwoWayResult 6178 if expectedResult == nil { 6179 expectedResult = c.Modified 6180 } 6181 return sortJsonOrFail(t, testObjectToJSONOrFail(t, c.Original), c.Description, schema), 6182 sortJsonOrFail(t, testObjectToJSONOrFail(t, c.TwoWay), c.Description, schema), 6183 sortJsonOrFail(t, testObjectToJSONOrFail(t, c.Modified), c.Description, schema), 6184 sortJsonOrFail(t, testObjectToJSONOrFail(t, expectedResult), c.Description, schema) 6185 } 6186 6187 func twoWayRawTestCaseToJSONOrFail(t *testing.T, c StrategicMergePatchRawTestCase) ([]byte, []byte, []byte, []byte) { 6188 expectedResult := c.TwoWayResult 6189 if expectedResult == nil { 6190 expectedResult = c.Modified 6191 } 6192 return yamlToJSONOrError(t, c.Original), 6193 yamlToJSONOrError(t, c.TwoWay), 6194 yamlToJSONOrError(t, c.Modified), 6195 yamlToJSONOrError(t, expectedResult) 6196 } 6197 6198 func testThreeWayPatch(t *testing.T, c StrategicMergePatchTestCase, schema LookupPatchMeta) { 6199 original, modified, current, expected, result := threeWayTestCaseToJSONOrFail(t, c, schema) 6200 actual, err := CreateThreeWayMergePatch(original, modified, current, schema, false) 6201 if err != nil { 6202 if !mergepatch.IsConflict(err) { 6203 t.Errorf("using %s error: %s\nin test case: %s\ncannot create three way patch:\n%s\n", 6204 getSchemaType(schema), err, c.Description, mergepatch.ToYAMLOrError(c.StrategicMergePatchTestCaseData)) 6205 return 6206 } 6207 6208 if !strings.Contains(c.Description, "conflict") { 6209 t.Errorf("using %s unexpected conflict: %s\nin test case: %s\ncannot create three way patch:\n%s\n", 6210 getSchemaType(schema), err, c.Description, mergepatch.ToYAMLOrError(c.StrategicMergePatchTestCaseData)) 6211 return 6212 } 6213 6214 if len(c.Result) > 0 { 6215 actual, err := CreateThreeWayMergePatch(original, modified, current, schema, true) 6216 if err != nil { 6217 t.Errorf("using %s error: %s\nin test case: %s\ncannot force three way patch application:\n%s\n", 6218 getSchemaType(schema), err, c.Description, mergepatch.ToYAMLOrError(c.StrategicMergePatchTestCaseData)) 6219 return 6220 } 6221 6222 testPatchCreation(t, expected, actual, c.Description) 6223 testPatchApplication(t, current, actual, result, c.Description, "", schema) 6224 } 6225 6226 return 6227 } 6228 6229 if strings.Contains(c.Description, "conflict") || len(c.Result) < 1 { 6230 t.Errorf("using %s error in test case: %s\nexpected conflict did not occur:\n%s\n", 6231 getSchemaType(schema), c.Description, mergepatch.ToYAMLOrError(c.StrategicMergePatchTestCaseData)) 6232 return 6233 } 6234 6235 testPatchCreation(t, expected, actual, c.Description) 6236 testPatchApplication(t, current, actual, result, c.Description, "", schema) 6237 } 6238 6239 func testThreeWayPatchForRawTestCase(t *testing.T, c StrategicMergePatchRawTestCase, schema LookupPatchMeta) { 6240 original, modified, current, expected, result := threeWayRawTestCaseToJSONOrFail(t, c) 6241 actual, err := CreateThreeWayMergePatch(original, modified, current, schema, false) 6242 if err != nil { 6243 if !mergepatch.IsConflict(err) { 6244 t.Errorf("using %s error: %s\nin test case: %s\ncannot create three way patch:\noriginal:%s\ntwoWay:%s\nmodified:%s\ncurrent:%s\nthreeWay:%s\nresult:%s\n", 6245 getSchemaType(schema), err, c.Description, c.Original, c.TwoWay, c.Modified, c.Current, c.ThreeWay, c.Result) 6246 return 6247 } 6248 6249 if !strings.Contains(c.Description, "conflict") { 6250 t.Errorf("using %s unexpected conflict: %s\nin test case: %s\ncannot create three way patch:\noriginal:%s\ntwoWay:%s\nmodified:%s\ncurrent:%s\nthreeWay:%s\nresult:%s\n", 6251 getSchemaType(schema), err, c.Description, c.Original, c.TwoWay, c.Modified, c.Current, c.ThreeWay, c.Result) 6252 return 6253 } 6254 6255 if len(c.Result) > 0 { 6256 actual, err := CreateThreeWayMergePatch(original, modified, current, schema, true) 6257 if err != nil { 6258 t.Errorf("using %s error: %s\nin test case: %s\ncannot force three way patch application:\noriginal:%s\ntwoWay:%s\nmodified:%s\ncurrent:%s\nthreeWay:%s\nresult:%s\n", 6259 getSchemaType(schema), err, c.Description, c.Original, c.TwoWay, c.Modified, c.Current, c.ThreeWay, c.Result) 6260 return 6261 } 6262 6263 testPatchCreation(t, expected, actual, c.Description) 6264 testPatchApplication(t, current, actual, result, c.Description, c.ExpectedError, schema) 6265 } 6266 6267 return 6268 } 6269 6270 if strings.Contains(c.Description, "conflict") || len(c.Result) < 1 { 6271 t.Errorf("using %s error: %s\nin test case: %s\nexpected conflict did not occur:\noriginal:%s\ntwoWay:%s\nmodified:%s\ncurrent:%s\nthreeWay:%s\nresult:%s\n", 6272 getSchemaType(schema), err, c.Description, c.Original, c.TwoWay, c.Modified, c.Current, c.ThreeWay, c.Result) 6273 return 6274 } 6275 6276 testPatchCreation(t, expected, actual, c.Description) 6277 testPatchApplication(t, current, actual, result, c.Description, c.ExpectedError, schema) 6278 } 6279 6280 func threeWayTestCaseToJSONOrFail(t *testing.T, c StrategicMergePatchTestCase, schema LookupPatchMeta) ([]byte, []byte, []byte, []byte, []byte) { 6281 return sortJsonOrFail(t, testObjectToJSONOrFail(t, c.Original), c.Description, schema), 6282 sortJsonOrFail(t, testObjectToJSONOrFail(t, c.Modified), c.Description, schema), 6283 sortJsonOrFail(t, testObjectToJSONOrFail(t, c.Current), c.Description, schema), 6284 sortJsonOrFail(t, testObjectToJSONOrFail(t, c.ThreeWay), c.Description, schema), 6285 sortJsonOrFail(t, testObjectToJSONOrFail(t, c.Result), c.Description, schema) 6286 } 6287 6288 func threeWayRawTestCaseToJSONOrFail(t *testing.T, c StrategicMergePatchRawTestCase) ([]byte, []byte, []byte, []byte, []byte) { 6289 return yamlToJSONOrError(t, c.Original), 6290 yamlToJSONOrError(t, c.Modified), 6291 yamlToJSONOrError(t, c.Current), 6292 yamlToJSONOrError(t, c.ThreeWay), 6293 yamlToJSONOrError(t, c.Result) 6294 } 6295 6296 func testPatchCreation(t *testing.T, expected, actual []byte, description string) { 6297 if !reflect.DeepEqual(actual, expected) { 6298 t.Errorf("error in test case: %s\nexpected patch:\n%s\ngot:\n%s\n", 6299 description, jsonToYAMLOrError(expected), jsonToYAMLOrError(actual)) 6300 return 6301 } 6302 } 6303 6304 func testPatchApplication(t *testing.T, original, patch, expected []byte, description, expectedError string, schema LookupPatchMeta) { 6305 result, err := StrategicMergePatchUsingLookupPatchMeta(original, patch, schema) 6306 if len(expectedError) != 0 { 6307 if err != nil && strings.Contains(err.Error(), expectedError) { 6308 return 6309 } 6310 t.Errorf("using %s expected error should contain:\n%s\nin test case: %s\nbut got:\n%s\n", getSchemaType(schema), expectedError, description, err) 6311 } 6312 if err != nil { 6313 t.Errorf("using %s error: %s\nin test case: %s\ncannot apply patch:\n%s\nto original:\n%s\n", 6314 getSchemaType(schema), err, description, jsonToYAMLOrError(patch), jsonToYAMLOrError(original)) 6315 return 6316 } 6317 6318 if !reflect.DeepEqual(result, expected) { 6319 format := "using error in test case: %s\npatch application failed:\noriginal:\n%s\npatch:\n%s\nexpected:\n%s\ngot:\n%s\n" 6320 t.Errorf(format, description, 6321 jsonToYAMLOrError(original), jsonToYAMLOrError(patch), 6322 jsonToYAMLOrError(expected), jsonToYAMLOrError(result)) 6323 return 6324 } 6325 } 6326 6327 func testObjectToJSONOrFail(t *testing.T, o map[string]interface{}) []byte { 6328 if o == nil { 6329 return nil 6330 } 6331 6332 j, err := toJSON(o) 6333 if err != nil { 6334 t.Error(err) 6335 } 6336 return j 6337 } 6338 6339 func sortJsonOrFail(t *testing.T, j []byte, description string, schema LookupPatchMeta) []byte { 6340 if j == nil { 6341 return nil 6342 } 6343 r, err := sortMergeListsByName(j, schema) 6344 if err != nil { 6345 t.Errorf("using %s error: %s\n in test case: %s\ncannot sort object:\n%s\n", getSchemaType(schema), err, description, j) 6346 return nil 6347 } 6348 6349 return r 6350 } 6351 6352 func getSchemaType(schema LookupPatchMeta) string { 6353 return reflect.TypeOf(schema).String() 6354 } 6355 6356 func jsonToYAMLOrError(j []byte) string { 6357 y, err := jsonToYAML(j) 6358 if err != nil { 6359 return err.Error() 6360 } 6361 6362 return string(y) 6363 } 6364 6365 func toJSON(v interface{}) ([]byte, error) { 6366 j, err := json.Marshal(v) 6367 if err != nil { 6368 return nil, fmt.Errorf("json marshal failed: %v\n%v\n", err, spew.Sdump(v)) 6369 } 6370 6371 return j, nil 6372 } 6373 6374 func jsonToYAML(j []byte) ([]byte, error) { 6375 y, err := yaml.JSONToYAML(j) 6376 if err != nil { 6377 return nil, fmt.Errorf("json to yaml failed: %v\n%v\n", err, j) 6378 } 6379 6380 return y, nil 6381 } 6382 6383 func yamlToJSON(y []byte) ([]byte, error) { 6384 j, err := yaml.YAMLToJSON(y) 6385 if err != nil { 6386 return nil, fmt.Errorf("yaml to json failed: %v\n%v\n", err, y) 6387 } 6388 6389 return j, nil 6390 } 6391 6392 func yamlToJSONOrError(t *testing.T, y []byte) []byte { 6393 j, err := yamlToJSON(y) 6394 if err != nil { 6395 t.Errorf("%v", err) 6396 } 6397 6398 return j 6399 } 6400 6401 type PrecisionItem struct { 6402 Name string `json:"name,omitempty"` 6403 Int32 int32 `json:"int32,omitempty"` 6404 Int64 int64 `json:"int64,omitempty"` 6405 Float32 float32 `json:"float32,omitempty"` 6406 Float64 float64 `json:"float64,omitempty"` 6407 } 6408 6409 var ( 6410 precisionItem PrecisionItem 6411 precisionItemStructSchema = PatchMetaFromStruct{T: GetTagStructTypeOrDie(precisionItem)} 6412 ) 6413 6414 func TestNumberConversion(t *testing.T) { 6415 testcases := map[string]struct { 6416 Old string 6417 New string 6418 ExpectedPatch string 6419 ExpectedResult string 6420 }{ 6421 "empty": { 6422 Old: `{}`, 6423 New: `{}`, 6424 ExpectedPatch: `{}`, 6425 ExpectedResult: `{}`, 6426 }, 6427 "int32 medium": { 6428 Old: `{"int32":1000000}`, 6429 New: `{"int32":1000000,"name":"newname"}`, 6430 ExpectedPatch: `{"name":"newname"}`, 6431 ExpectedResult: `{"int32":1000000,"name":"newname"}`, 6432 }, 6433 "int32 max": { 6434 Old: `{"int32":2147483647}`, 6435 New: `{"int32":2147483647,"name":"newname"}`, 6436 ExpectedPatch: `{"name":"newname"}`, 6437 ExpectedResult: `{"int32":2147483647,"name":"newname"}`, 6438 }, 6439 "int64 medium": { 6440 Old: `{"int64":1000000}`, 6441 New: `{"int64":1000000,"name":"newname"}`, 6442 ExpectedPatch: `{"name":"newname"}`, 6443 ExpectedResult: `{"int64":1000000,"name":"newname"}`, 6444 }, 6445 "int64 max": { 6446 Old: `{"int64":9223372036854775807}`, 6447 New: `{"int64":9223372036854775807,"name":"newname"}`, 6448 ExpectedPatch: `{"name":"newname"}`, 6449 ExpectedResult: `{"int64":9223372036854775807,"name":"newname"}`, 6450 }, 6451 "float32 max": { 6452 Old: `{"float32":3.4028234663852886e+38}`, 6453 New: `{"float32":3.4028234663852886e+38,"name":"newname"}`, 6454 ExpectedPatch: `{"name":"newname"}`, 6455 ExpectedResult: `{"float32":3.4028234663852886e+38,"name":"newname"}`, 6456 }, 6457 "float64 max": { 6458 Old: `{"float64":1.7976931348623157e+308}`, 6459 New: `{"float64":1.7976931348623157e+308,"name":"newname"}`, 6460 ExpectedPatch: `{"name":"newname"}`, 6461 ExpectedResult: `{"float64":1.7976931348623157e+308,"name":"newname"}`, 6462 }, 6463 } 6464 6465 precisionItemOpenapiSchema := PatchMetaFromOpenAPI{ 6466 Schema: sptest.GetSchemaOrDie(&fakePrecisionItemSchema, "precisionItem"), 6467 } 6468 precisionItemSchemas := []LookupPatchMeta{ 6469 precisionItemStructSchema, 6470 precisionItemOpenapiSchema, 6471 } 6472 6473 for _, schema := range precisionItemSchemas { 6474 for k, tc := range testcases { 6475 patch, err := CreateTwoWayMergePatchUsingLookupPatchMeta([]byte(tc.Old), []byte(tc.New), schema) 6476 if err != nil { 6477 t.Errorf("using %s in testcase %s: unexpected error %v", getSchemaType(schema), k, err) 6478 continue 6479 } 6480 if tc.ExpectedPatch != string(patch) { 6481 t.Errorf("using %s in testcase %s: expected %s, got %s", getSchemaType(schema), k, tc.ExpectedPatch, string(patch)) 6482 continue 6483 } 6484 6485 result, err := StrategicMergePatchUsingLookupPatchMeta([]byte(tc.Old), patch, schema) 6486 if err != nil { 6487 t.Errorf("using %s in testcase %s: unexpected error %v", getSchemaType(schema), k, err) 6488 continue 6489 } 6490 if tc.ExpectedResult != string(result) { 6491 t.Errorf("using %s in testcase %s: expected %s, got %s", getSchemaType(schema), k, tc.ExpectedResult, string(result)) 6492 continue 6493 } 6494 } 6495 } 6496 } 6497 6498 var replaceRawExtensionPatchTestCases = []StrategicMergePatchRawTestCase{ 6499 { 6500 Description: "replace RawExtension field, rest unchanched", 6501 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 6502 Original: []byte(` 6503 name: my-object 6504 value: some-value 6505 other: current-other 6506 replacingItem: 6507 Some: Generic 6508 Yaml: Inside 6509 The: RawExtension 6510 Field: Period 6511 `), 6512 Current: []byte(` 6513 name: my-object 6514 value: some-value 6515 other: current-other 6516 mergingList: 6517 - name: 1 6518 - name: 2 6519 - name: 3 6520 replacingItem: 6521 Some: Generic 6522 Yaml: Inside 6523 The: RawExtension 6524 Field: Period 6525 `), 6526 Modified: []byte(` 6527 name: my-object 6528 value: some-value 6529 other: current-other 6530 mergingList: 6531 - name: 1 6532 - name: 2 6533 - name: 3 6534 replacingItem: 6535 Newly: Modified 6536 Yaml: Inside 6537 The: RawExtension 6538 `), 6539 TwoWay: []byte(` 6540 mergingList: 6541 - name: 1 6542 - name: 2 6543 - name: 3 6544 replacingItem: 6545 Newly: Modified 6546 Yaml: Inside 6547 The: RawExtension 6548 `), 6549 TwoWayResult: []byte(` 6550 name: my-object 6551 value: some-value 6552 other: current-other 6553 mergingList: 6554 - name: 1 6555 - name: 2 6556 - name: 3 6557 replacingItem: 6558 Newly: Modified 6559 Yaml: Inside 6560 The: RawExtension 6561 `), 6562 ThreeWay: []byte(` 6563 replacingItem: 6564 Newly: Modified 6565 Yaml: Inside 6566 The: RawExtension 6567 `), 6568 Result: []byte(` 6569 name: my-object 6570 value: some-value 6571 other: current-other 6572 mergingList: 6573 - name: 1 6574 - name: 2 6575 - name: 3 6576 replacingItem: 6577 Newly: Modified 6578 Yaml: Inside 6579 The: RawExtension 6580 `), 6581 }, 6582 }, 6583 { 6584 Description: "replace RawExtension field and merge list", 6585 StrategicMergePatchRawTestCaseData: StrategicMergePatchRawTestCaseData{ 6586 Original: []byte(` 6587 name: my-object 6588 value: some-value 6589 other: current-other 6590 mergingList: 6591 - name: 1 6592 replacingItem: 6593 Some: Generic 6594 Yaml: Inside 6595 The: RawExtension 6596 Field: Period 6597 `), 6598 Current: []byte(` 6599 name: my-object 6600 value: some-value 6601 other: current-other 6602 mergingList: 6603 - name: 1 6604 - name: 3 6605 replacingItem: 6606 Some: Generic 6607 Yaml: Inside 6608 The: RawExtension 6609 Field: Period 6610 `), 6611 Modified: []byte(` 6612 name: my-object 6613 value: some-value 6614 other: current-other 6615 mergingList: 6616 - name: 1 6617 - name: 2 6618 replacingItem: 6619 Newly: Modified 6620 Yaml: Inside 6621 The: RawExtension 6622 `), 6623 TwoWay: []byte(` 6624 $setElementOrder/mergingList: 6625 - name: 1 6626 - name: 2 6627 mergingList: 6628 - name: 2 6629 replacingItem: 6630 Newly: Modified 6631 Yaml: Inside 6632 The: RawExtension 6633 `), 6634 TwoWayResult: []byte(` 6635 name: my-object 6636 value: some-value 6637 other: current-other 6638 mergingList: 6639 - name: 1 6640 - name: 2 6641 replacingItem: 6642 Newly: Modified 6643 Yaml: Inside 6644 The: RawExtension 6645 `), 6646 ThreeWay: []byte(` 6647 $setElementOrder/mergingList: 6648 - name: 1 6649 - name: 2 6650 mergingList: 6651 - name: 2 6652 replacingItem: 6653 Newly: Modified 6654 Yaml: Inside 6655 The: RawExtension 6656 `), 6657 Result: []byte(` 6658 name: my-object 6659 value: some-value 6660 other: current-other 6661 mergingList: 6662 - name: 1 6663 - name: 2 6664 - name: 3 6665 replacingItem: 6666 Newly: Modified 6667 Yaml: Inside 6668 The: RawExtension 6669 `), 6670 }, 6671 }, 6672 } 6673 6674 func TestReplaceWithRawExtension(t *testing.T) { 6675 mergeItemOpenapiSchema := PatchMetaFromOpenAPI{ 6676 Schema: sptest.GetSchemaOrDie(&fakeMergeItemSchema, "mergeItem"), 6677 } 6678 schemas := []LookupPatchMeta{ 6679 mergeItemStructSchema, 6680 mergeItemOpenapiSchema, 6681 } 6682 6683 for _, schema := range schemas { 6684 for _, c := range replaceRawExtensionPatchTestCases { 6685 testTwoWayPatchForRawTestCase(t, c, schema) 6686 testThreeWayPatchForRawTestCase(t, c, schema) 6687 } 6688 } 6689 } 6690 6691 func TestUnknownField(t *testing.T) { 6692 testcases := map[string]struct { 6693 Original string 6694 Current string 6695 Modified string 6696 6697 ExpectedTwoWay string 6698 ExpectedTwoWayErr string 6699 ExpectedTwoWayResult string 6700 ExpectedThreeWay string 6701 ExpectedThreeWayErr string 6702 ExpectedThreeWayResult string 6703 }{ 6704 // cases we can successfully strategically merge 6705 "no diff": { 6706 Original: `{"array":[1,2,3],"complex":{"nested":true},"name":"foo","scalar":true}`, 6707 Current: `{"array":[1,2,3],"complex":{"nested":true},"name":"foo","scalar":true}`, 6708 Modified: `{"array":[1,2,3],"complex":{"nested":true},"name":"foo","scalar":true}`, 6709 6710 ExpectedTwoWay: `{}`, 6711 ExpectedTwoWayResult: `{"array":[1,2,3],"complex":{"nested":true},"name":"foo","scalar":true}`, 6712 ExpectedThreeWay: `{}`, 6713 ExpectedThreeWayResult: `{"array":[1,2,3],"complex":{"nested":true},"name":"foo","scalar":true}`, 6714 }, 6715 "no diff even if modified null": { 6716 Original: `{"array":[1,2,3],"complex":{"nested":true},"name":"foo","scalar":true}`, 6717 Current: `{"array":[1,2,3],"complex":{"nested":true},"name":"foo","scalar":true}`, 6718 Modified: `{"array":[1,2,3],"complex":{"nested":true},"complex_nullable":{"key":null},"name":"foo","scalar":true}`, 6719 6720 ExpectedTwoWay: `{"complex_nullable":{"key":null}}`, 6721 ExpectedTwoWayResult: `{"array":[1,2,3],"complex":{"nested":true},"complex_nullable":{},"name":"foo","scalar":true}`, 6722 ExpectedThreeWay: `{"complex_nullable":{"key":null}}`, 6723 ExpectedThreeWayResult: `{"array":[1,2,3],"complex":{"nested":true},"complex_nullable":{},"name":"foo","scalar":true}`, 6724 }, 6725 "discard nulls in nested and adds not nulls": { 6726 Original: `{"array":[1,2,3],"complex":{"nested":true},"name":"foo","scalar":true}`, 6727 Current: `{"array":[1,2,3],"complex":{"nested":true},"name":"foo","scalar":true}`, 6728 Modified: `{"array":[1,2,3],"complex":{"nested":true},"complex_nullable":{"key":{"keynotnull":"value","keynull":null}},"name":"foo","scalar":true}`, 6729 6730 ExpectedTwoWay: `{"complex_nullable":{"key":{"keynotnull":"value","keynull":null}}}`, 6731 ExpectedTwoWayResult: `{"array":[1,2,3],"complex":{"nested":true},"complex_nullable":{"key":{"keynotnull":"value"}},"name":"foo","scalar":true}`, 6732 ExpectedThreeWay: `{"complex_nullable":{"key":{"keynotnull":"value","keynull":null}}}`, 6733 ExpectedThreeWayResult: `{"array":[1,2,3],"complex":{"nested":true},"complex_nullable":{"key":{"keynotnull":"value"}},"name":"foo","scalar":true}`, 6734 }, 6735 "discard if modified all nulls": { 6736 Original: `{}`, 6737 Current: `{}`, 6738 Modified: `{"complex":{"nested":null}}`, 6739 6740 ExpectedTwoWay: `{"complex":{"nested":null}}`, 6741 ExpectedTwoWayResult: `{"complex":{}}`, 6742 ExpectedThreeWay: `{"complex":{"nested":null}}`, 6743 ExpectedThreeWayResult: `{"complex":{}}`, 6744 }, 6745 "add only not nulls": { 6746 Original: `{}`, 6747 Current: `{}`, 6748 Modified: `{"complex":{"nested":null,"nested2":"foo"}}`, 6749 6750 ExpectedTwoWay: `{"complex":{"nested":null,"nested2":"foo"}}`, 6751 ExpectedTwoWayResult: `{"complex":{"nested2":"foo"}}`, 6752 ExpectedThreeWay: `{"complex":{"nested":null,"nested2":"foo"}}`, 6753 ExpectedThreeWayResult: `{"complex":{"nested2":"foo"}}`, 6754 }, 6755 "null values in original are preserved": { 6756 Original: `{"thing":null}`, 6757 Current: `{"thing":null}`, 6758 Modified: `{"nested":{"value":5},"thing":null}`, 6759 6760 ExpectedTwoWay: `{"nested":{"value":5}}`, 6761 ExpectedTwoWayResult: `{"nested":{"value":5},"thing":null}`, 6762 ExpectedThreeWay: `{"nested":{"value":5}}`, 6763 ExpectedThreeWayResult: `{"nested":{"value":5},"thing":null}`, 6764 }, 6765 "nested null values in original are preserved": { 6766 Original: `{"complex":{"key":null},"thing":null}`, 6767 Current: `{"complex":{"key":null},"thing":null}`, 6768 Modified: `{"complex":{"key":null},"nested":{"value":5},"thing":null}`, 6769 6770 ExpectedTwoWay: `{"nested":{"value":5}}`, 6771 ExpectedTwoWayResult: `{"complex":{"key":null},"nested":{"value":5},"thing":null}`, 6772 ExpectedThreeWay: `{"nested":{"value":5}}`, 6773 ExpectedThreeWayResult: `{"complex":{"key":null},"nested":{"value":5},"thing":null}`, 6774 }, 6775 "add empty slices": { 6776 Original: `{"array":[1,2,3],"complex":{"nested":true},"name":"foo","scalar":true}`, 6777 Current: `{"array":[1,2,3],"complex":{"nested":true},"name":"foo","scalar":true}`, 6778 Modified: `{"array":[1,2,3],"complex":{"nested":true},"complex_nullable":[],"name":"foo","scalar":true}`, 6779 6780 ExpectedTwoWay: `{"complex_nullable":[]}`, 6781 ExpectedTwoWayResult: `{"array":[1,2,3],"complex":{"nested":true},"complex_nullable":[],"name":"foo","scalar":true}`, 6782 ExpectedThreeWay: `{"complex_nullable":[]}`, 6783 ExpectedThreeWayResult: `{"array":[1,2,3],"complex":{"nested":true},"complex_nullable":[],"name":"foo","scalar":true}`, 6784 }, 6785 "filter nulls from nested slices": { 6786 Original: `{}`, 6787 Current: `{}`, 6788 Modified: `{"complex_nullable":[{"inner_one":{"key_one":"foo","key_two":null}}]}`, 6789 6790 ExpectedTwoWay: `{"complex_nullable":[{"inner_one":{"key_one":"foo","key_two":null}}]}`, 6791 ExpectedTwoWayResult: `{"complex_nullable":[{"inner_one":{"key_one":"foo"}}]}`, 6792 ExpectedThreeWay: `{"complex_nullable":[{"inner_one":{"key_one":"foo","key_two":null}}]}`, 6793 ExpectedThreeWayResult: `{"complex_nullable":[{"inner_one":{"key_one":"foo"}}]}`, 6794 }, 6795 "filter if slice is all empty": { 6796 Original: `{}`, 6797 Current: `{}`, 6798 Modified: `{"complex_nullable":[{"inner_one":{"key_one":null,"key_two":null}}]}`, 6799 6800 ExpectedTwoWay: `{"complex_nullable":[{"inner_one":{"key_one":null,"key_two":null}}]}`, 6801 ExpectedTwoWayResult: `{"complex_nullable":[{"inner_one":{}}]}`, 6802 ExpectedThreeWay: `{"complex_nullable":[{"inner_one":{"key_one":null,"key_two":null}}]}`, 6803 ExpectedThreeWayResult: `{"complex_nullable":[{"inner_one":{}}]}`, 6804 }, 6805 "not filter nulls from non-associative slice": { 6806 Original: `{}`, 6807 Current: `{}`, 6808 Modified: `{"complex_nullable":["key1",null,"key2"]}`, 6809 6810 ExpectedTwoWay: `{"complex_nullable":["key1",null,"key2"]}`, 6811 ExpectedTwoWayResult: `{"complex_nullable":["key1",null,"key2"]}`, 6812 ExpectedThreeWay: `{"complex_nullable":["key1",null,"key2"]}`, 6813 ExpectedThreeWayResult: `{"complex_nullable":["key1",null,"key2"]}`, 6814 }, 6815 "added only": { 6816 Original: `{"name":"foo"}`, 6817 Current: `{"name":"foo"}`, 6818 Modified: `{"name":"foo","scalar":true,"complex":{"nested":true},"array":[1,2,3]}`, 6819 6820 ExpectedTwoWay: `{"array":[1,2,3],"complex":{"nested":true},"scalar":true}`, 6821 ExpectedTwoWayResult: `{"array":[1,2,3],"complex":{"nested":true},"name":"foo","scalar":true}`, 6822 ExpectedThreeWay: `{"array":[1,2,3],"complex":{"nested":true},"scalar":true}`, 6823 ExpectedThreeWayResult: `{"array":[1,2,3],"complex":{"nested":true},"name":"foo","scalar":true}`, 6824 }, 6825 "removed only": { 6826 Original: `{"name":"foo","scalar":true,"complex":{"nested":true}}`, 6827 Current: `{"name":"foo","scalar":true,"complex":{"nested":true},"array":[1,2,3]}`, 6828 Modified: `{"name":"foo"}`, 6829 6830 ExpectedTwoWay: `{"complex":null,"scalar":null}`, 6831 ExpectedTwoWayResult: `{"name":"foo"}`, 6832 ExpectedThreeWay: `{"complex":null,"scalar":null}`, 6833 ExpectedThreeWayResult: `{"array":[1,2,3],"name":"foo"}`, 6834 }, 6835 6836 // cases we cannot successfully strategically merge (expect errors) 6837 "diff": { 6838 Original: `{"array":[1,2,3],"complex":{"nested":true},"name":"foo","scalar":true}`, 6839 Current: `{"array":[1,2,3],"complex":{"nested":true},"name":"foo","scalar":true}`, 6840 Modified: `{"array":[1,2,3],"complex":{"nested":false},"name":"foo","scalar":true}`, 6841 6842 ExpectedTwoWayErr: `unable to find api field`, 6843 ExpectedThreeWayErr: `unable to find api field`, 6844 }, 6845 } 6846 6847 mergeItemOpenapiSchema := PatchMetaFromOpenAPI{ 6848 Schema: sptest.GetSchemaOrDie(&fakeMergeItemSchema, "mergeItem"), 6849 } 6850 schemas := []LookupPatchMeta{ 6851 mergeItemStructSchema, 6852 mergeItemOpenapiSchema, 6853 } 6854 6855 for _, k := range sets.StringKeySet(testcases).List() { 6856 tc := testcases[k] 6857 for _, schema := range schemas { 6858 func() { 6859 twoWay, err := CreateTwoWayMergePatchUsingLookupPatchMeta([]byte(tc.Original), []byte(tc.Modified), schema) 6860 if err != nil { 6861 if len(tc.ExpectedTwoWayErr) == 0 { 6862 t.Errorf("using %s in testcase %s: error making two-way patch: %v", getSchemaType(schema), k, err) 6863 } 6864 if !strings.Contains(err.Error(), tc.ExpectedTwoWayErr) { 6865 t.Errorf("using %s in testcase %s: expected error making two-way patch to contain '%s', got %s", getSchemaType(schema), k, tc.ExpectedTwoWayErr, err) 6866 } 6867 return 6868 } 6869 6870 if string(twoWay) != tc.ExpectedTwoWay { 6871 t.Errorf("using %s in testcase %s: expected two-way patch:\n\t%s\ngot\n\t%s", getSchemaType(schema), k, string(tc.ExpectedTwoWay), string(twoWay)) 6872 return 6873 } 6874 6875 twoWayResult, err := StrategicMergePatchUsingLookupPatchMeta([]byte(tc.Original), twoWay, schema) 6876 if err != nil { 6877 t.Errorf("using %s in testcase %s: error applying two-way patch: %v", getSchemaType(schema), k, err) 6878 return 6879 } 6880 if string(twoWayResult) != tc.ExpectedTwoWayResult { 6881 t.Errorf("using %s in testcase %s: expected two-way result:\n\t%s\ngot\n\t%s", getSchemaType(schema), k, string(tc.ExpectedTwoWayResult), string(twoWayResult)) 6882 return 6883 } 6884 }() 6885 6886 func() { 6887 threeWay, err := CreateThreeWayMergePatch([]byte(tc.Original), []byte(tc.Modified), []byte(tc.Current), schema, false) 6888 if err != nil { 6889 if len(tc.ExpectedThreeWayErr) == 0 { 6890 t.Errorf("using %s in testcase %s: error making three-way patch: %v", getSchemaType(schema), k, err) 6891 } else if !strings.Contains(err.Error(), tc.ExpectedThreeWayErr) { 6892 t.Errorf("using %s in testcase %s: expected error making three-way patch to contain '%s', got %s", getSchemaType(schema), k, tc.ExpectedThreeWayErr, err) 6893 } 6894 return 6895 } 6896 6897 if string(threeWay) != tc.ExpectedThreeWay { 6898 t.Errorf("using %s in testcase %s: expected three-way patch:\n\t%s\ngot\n\t%s", getSchemaType(schema), k, string(tc.ExpectedThreeWay), string(threeWay)) 6899 return 6900 } 6901 6902 threeWayResult, err := StrategicMergePatch([]byte(tc.Current), threeWay, schema) 6903 if err != nil { 6904 t.Errorf("using %s in testcase %s: error applying three-way patch: %v", getSchemaType(schema), k, err) 6905 return 6906 } else if string(threeWayResult) != tc.ExpectedThreeWayResult { 6907 t.Errorf("using %s in testcase %s: expected three-way result:\n\t%s\ngot\n\t%s", getSchemaType(schema), k, string(tc.ExpectedThreeWayResult), string(threeWayResult)) 6908 return 6909 } 6910 }() 6911 } 6912 } 6913 }