Skip to content

Commit

Permalink
fix: add unit tests to Row
Browse files Browse the repository at this point in the history
### What changes were proposed in this pull request?

#75 shows that `Row` type has a bug.

I added tests to the `Row` types.

### Why are the changes needed?

To guarantee bug free implementation of `Row` type.

### Does this PR introduce _any_ user-facing change?

No

### How was this patch tested?

The PR adds unit-tests for the `Row` type.

fixes #76

Signed-off-by: Mustafa Elbehery <melbeherredhat.com>

Closes #77 from Elbehery/76_test_row.

Authored-by: Mustafa Elbehery <melbeher@redhat.com>
Signed-off-by: Martin Grund <martin.grund@databricks.com>
  • Loading branch information
Elbehery authored and grundprinzip committed Oct 21, 2024
1 parent 7e10ae5 commit e29b941
Show file tree
Hide file tree
Showing 2 changed files with 124 additions and 1 deletion.
15 changes: 14 additions & 1 deletion spark/sql/types/row.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,15 @@
package types

type Row interface {
// At returns field's value at the given index within a [Row].
// It returns nil for invalid indices.
At(index int) any
// Value returns field's value of the given column's name within a [Row].
// It returns nil for invalid column's name.
Value(name string) any
// Values returns values of all fields within a [Row] as a slice of any.
Values() []any
// Len returns the number of fields within a [Row]
Len() int
FieldNames() []string
}
Expand All @@ -30,11 +36,18 @@ type rowImpl struct {
}

func (r *rowImpl) At(index int) any {
if index < 0 || index > len(r.values) {
return nil
}
return r.values[index]
}

func (r *rowImpl) Value(name string) any {
return r.values[r.offsets[name]]
idx, ok := r.offsets[name]
if !ok {
return nil
}
return r.values[idx]
}

func (r *rowImpl) Values() []any {
Expand Down
110 changes: 110 additions & 0 deletions spark/sql/types/row_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
//
// Licensed to the Apache Software Foundation (ASF) under one or more
// contributor license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright ownership.
// The ASF licenses this file to You under the Apache License, Version 2.0
// (the "License"); you may not use this file except in compliance with
// the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package types

import (
"testing"

"github.com/stretchr/testify/require"
)

// rowImplTest is a read-only sample [Row] to be used in all tests.
var rowImplSample rowImpl = rowImpl{
values: []any{1, 2, 3, 4, 5},
offsets: map[string]int{
"one": 0,
"two": 1,
"three": 2,
"four": 3,
"five": 4,
},
}

func TestRowImpl_At(t *testing.T) {
testCases := []struct {
name string
input int
exp any
}{
{
name: "index within range",
input: 2,
exp: 3,
},
{
name: "index out of range",
input: 6,
exp: nil,
},
{
name: "negative index",
input: -1,
exp: nil,
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
act := rowImplSample.At(tc.input)
require.Equal(t, tc.exp, act)
})
}
}

func TestRowImpl_Value(t *testing.T) {
testCases := []struct {
name string
input string
exp any
}{
{
name: "valid field name",
input: "two",
exp: 2,
},
{
name: "invalid field name",
input: "six",
exp: nil,
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
act := rowImplSample.Value(tc.input)
require.Equal(t, tc.exp, act)
})
}
}

func TestRowImpl_Values(t *testing.T) {
exp := []any{1, 2, 3, 4, 5}
act := rowImplSample.Values()
require.Equal(t, exp, act)
}

func TestRowImpl_Len(t *testing.T) {
exp := 5
act := rowImplSample.Len()
require.Equal(t, exp, act)
}

func TestRowImpl_FieldNames(t *testing.T) {
exp := []string{"one", "two", "three", "four", "five"}
act := rowImplSample.FieldNames()
require.ElementsMatch(t, exp, act)
}

0 comments on commit e29b941

Please sign in to comment.