github.com/hasnat/dolt/go@v0.0.0-20210628190320-9eb5d843fbb7/store/merge/three_way_test.go (about) 1 // Copyright 2019 Dolthub, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 // 15 // This file incorporates work covered by the following copyright and 16 // permission notice: 17 // 18 // Copyright 2016 Attic Labs, Inc. All rights reserved. 19 // Licensed under the Apache License, version 2.0: 20 // http://www.apache.org/licenses/LICENSE-2.0 21 22 package merge 23 24 import ( 25 "context" 26 "testing" 27 28 "github.com/stretchr/testify/assert" 29 "github.com/stretchr/testify/suite" 30 31 "github.com/dolthub/dolt/go/store/chunks" 32 "github.com/dolthub/dolt/go/store/d" 33 "github.com/dolthub/dolt/go/store/types" 34 ) 35 36 func mustValue(val types.Value, err error) types.Value { 37 d.PanicIfError(err) 38 return val 39 } 40 41 func mustString(str string, err error) string { 42 d.PanicIfError(err) 43 return str 44 } 45 46 type seq interface { 47 items() []interface{} 48 } 49 50 type ThreeWayMergeSuite struct { 51 suite.Suite 52 vs *types.ValueStore 53 create func(seq) (types.Value, error) 54 typeStr string 55 } 56 57 func (s *ThreeWayMergeSuite) SetupTest() { 58 storage := &chunks.MemoryStorage{} 59 s.vs = types.NewValueStore(storage.NewView()) 60 } 61 62 func (s *ThreeWayMergeSuite) TearDownTest() { 63 err := s.vs.Close() 64 s.NoError(err) 65 } 66 67 func (s *ThreeWayMergeSuite) tryThreeWayMerge(a, b, p, exp seq) { 68 aVal, err := s.create(a) 69 s.NoError(err) 70 bVal, err := s.create(b) 71 s.NoError(err) 72 pVal, err := s.create(p) 73 s.NoError(err) 74 merged, err := ThreeWay(context.Background(), aVal, bVal, pVal, s.vs, nil, nil) 75 if s.NoError(err) { 76 expected, err := s.create(exp) 77 s.NoError(err) 78 s.True(expected.Equals(merged), "%s != %s", mustString(types.EncodedValue(context.Background(), expected)), mustString(types.EncodedValue(context.Background(), merged))) 79 } 80 } 81 82 func (s *ThreeWayMergeSuite) tryThreeWayConflict(a, b, p types.Value, contained string) { 83 m, err := ThreeWay(context.Background(), a, b, p, s.vs, nil, nil) 84 if s.Error(err) { 85 s.Contains(err.Error(), contained) 86 return 87 } 88 s.Fail("Expected error!", "Got successful merge: %s", mustString(types.EncodedValue(context.Background(), m))) 89 } 90 91 func valsToTypesValues(f func(seq) (types.Value, error), items ...interface{}) ([]types.Value, error) { 92 keyValues := []types.Value{} 93 for _, e := range items { 94 v, err := valToTypesValue(f, e) 95 96 if err != nil { 97 return nil, err 98 } 99 100 keyValues = append(keyValues, v) 101 } 102 return keyValues, nil 103 } 104 105 func valToTypesValue(f func(seq) (types.Value, error), v interface{}) (types.Value, error) { 106 var v1 types.Value 107 var err error 108 switch t := v.(type) { 109 case string: 110 v1 = types.String(t) 111 case int: 112 v1 = types.Float(t) 113 case seq: 114 v1, err = f(t) 115 case types.Value: 116 v1 = t 117 } 118 return v1, err 119 } 120 121 func TestThreeWayMerge_PrimitiveConflict(t *testing.T) { 122 threeWayConflict := func(a, b, p types.Value, contained string) { 123 mrgr := &merger{} 124 m, err := mrgr.threeWay(context.Background(), a, b, p, nil) 125 if assert.Error(t, err) { 126 assert.Contains(t, err.Error(), contained) 127 return 128 } 129 assert.Fail(t, "Expected error!", "Got successful merge: %s", mustString(types.EncodedValue(context.Background(), m))) 130 } 131 132 a, b, p := types.Float(7), types.String("nope"), types.String("parent") 133 134 threeWayConflict(a, b, p, "Float and String on top of") 135 threeWayConflict(b, a, p, "String and Float on top of") 136 }