github.com/hasnat/dolt/go@v0.0.0-20210628190320-9eb5d843fbb7/libraries/doltcore/rowconv/joiner_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 package rowconv 16 17 import ( 18 "testing" 19 20 "github.com/stretchr/testify/assert" 21 "github.com/stretchr/testify/require" 22 23 "github.com/dolthub/dolt/go/libraries/doltcore/row" 24 "github.com/dolthub/dolt/go/libraries/doltcore/schema" 25 "github.com/dolthub/dolt/go/store/types" 26 ) 27 28 const ( 29 firstTag uint64 = iota 30 lastTag 31 ageTag 32 cityTag 33 ) 34 35 var peopleCols = schema.NewColCollection( 36 schema.NewColumn("last", lastTag, types.StringKind, true), 37 schema.NewColumn("first", firstTag, types.StringKind, true), 38 schema.NewColumn("age", ageTag, types.IntKind, false), 39 schema.NewColumn("city", cityTag, types.StringKind, false), 40 ) 41 42 var peopleSch = schema.MustSchemaFromCols(peopleCols) 43 44 type toJoinAndExpectedResult struct { 45 toJoinVals map[string]row.TaggedValues 46 expected map[string]types.Value 47 } 48 49 func TestJoiner(t *testing.T) { 50 tests := []struct { 51 name string 52 namedSchemas []NamedSchema 53 namers map[string]ColNamingFunc 54 toJoin []toJoinAndExpectedResult 55 }{ 56 { 57 name: "join diff versions of row", 58 namedSchemas: []NamedSchema{{"to", peopleSch}, {"from", peopleSch}}, 59 namers: map[string]ColNamingFunc{"to": toNamer, "from": fromNamer}, 60 toJoin: []toJoinAndExpectedResult{ 61 { 62 toJoinVals: map[string]row.TaggedValues{ 63 "from": { 64 lastTag: types.String("Richardson"), 65 firstTag: types.String("Richard"), 66 ageTag: types.Int(42), 67 cityTag: types.String("San Francisco"), 68 }, 69 "to": { 70 lastTag: types.String("Richardson"), 71 firstTag: types.String("Richard"), 72 ageTag: types.Int(43), 73 cityTag: types.String("Los Angeles"), 74 }, 75 }, 76 expected: map[string]types.Value{ 77 "from_last": types.String("Richardson"), 78 "from_first": types.String("Richard"), 79 "from_city": types.String("San Francisco"), 80 "from_age": types.Int(42), 81 82 "to_last": types.String("Richardson"), 83 "to_first": types.String("Richard"), 84 "to_city": types.String("Los Angeles"), 85 "to_age": types.Int(43), 86 }, 87 }, 88 { 89 toJoinVals: map[string]row.TaggedValues{ 90 "from": { 91 lastTag: types.String("Richardson"), 92 firstTag: types.String("Richard"), 93 ageTag: types.Int(42), 94 cityTag: types.String("San Francisco"), 95 }, 96 }, 97 expected: map[string]types.Value{ 98 "from_last": types.String("Richardson"), 99 "from_first": types.String("Richard"), 100 "from_city": types.String("San Francisco"), 101 "from_age": types.Int(42), 102 }, 103 }, 104 { 105 toJoinVals: map[string]row.TaggedValues{ 106 "to": { 107 lastTag: types.String("Richardson"), 108 firstTag: types.String("Richard"), 109 ageTag: types.Int(43), 110 cityTag: types.String("Los Angeles"), 111 }, 112 }, 113 expected: map[string]types.Value{ 114 "to_last": types.String("Richardson"), 115 "to_first": types.String("Richard"), 116 "to_city": types.String("Los Angeles"), 117 "to_age": types.Int(43), 118 }, 119 }, 120 }, 121 }, 122 } 123 124 for _, test := range tests { 125 t.Run(test.name, func(t *testing.T) { 126 j, err := NewJoiner(test.namedSchemas, test.namers) 127 require.NoError(t, err) 128 129 for _, tj := range test.toJoin { 130 rows := map[string]row.Row{} 131 132 for _, namedSch := range test.namedSchemas { 133 r, err := row.New(types.Format_Default, namedSch.Sch, tj.toJoinVals[namedSch.Name]) 134 require.NoError(t, err) 135 136 rows[namedSch.Name] = r 137 } 138 139 joinedRow, err := j.Join(rows) 140 require.NoError(t, err) 141 142 joinedSch := j.GetSchema() 143 _, err = joinedRow.IterCols(func(tag uint64, val types.Value) (stop bool, err error) { 144 col, ok := joinedSch.GetAllCols().GetByTag(tag) 145 assert.True(t, ok) 146 147 expectedVal := tj.expected[col.Name] 148 assert.Equal(t, val, expectedVal) 149 150 return false, nil 151 }) 152 153 require.NoError(t, err) 154 155 splitRows, err := j.Split(joinedRow) 156 require.NoError(t, err) 157 158 assert.Equal(t, len(tj.toJoinVals), len(splitRows)) 159 160 for _, namedSch := range test.namedSchemas { 161 name := namedSch.Name 162 sch := namedSch.Sch 163 actual := splitRows[name] 164 expectedVals := tj.toJoinVals[name] 165 166 if actual == nil && expectedVals == nil { 167 continue 168 } 169 170 assert.False(t, actual == nil || expectedVals == nil) 171 172 expected, err := row.New(types.Format_Default, sch, expectedVals) 173 require.NoError(t, err) 174 assert.True(t, row.AreEqual(actual, expected, sch)) 175 } 176 } 177 }) 178 } 179 } 180 181 func fromNamer(name string) string { 182 return "from_" + name 183 } 184 185 func toNamer(name string) string { 186 return "to_" + name 187 }