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  }