Add tests to the modifiers package

pull/29/head
Vinícius Garcia 2022-09-23 22:49:41 -03:00
parent 41f4d5487b
commit 9e94445cdc
6 changed files with 281 additions and 0 deletions

View File

@ -0,0 +1,63 @@
package modifiers
import (
"context"
"errors"
"testing"
tt "github.com/vingarcia/ksql/internal/testtools"
)
func TestAttrWrapper(t *testing.T) {
ctx := context.Background()
var scanArgs map[string]interface{}
var valueArgs map[string]interface{}
wrapper := AttrWrapper{
Ctx: ctx,
Attr: "fakeAttr",
Modifier: AttrModifierMock{
AttrScanFn: func(ctx context.Context, opInfo OpInfo, attrPtr interface{}, dbValue interface{}) error {
scanArgs = map[string]interface{}{
"opInfo": opInfo,
"attrPtr": attrPtr,
"dbValue": dbValue,
}
return errors.New("fakeScanErrMsg")
},
AttrValueFn: func(ctx context.Context, opInfo OpInfo, inputValue interface{}) (outputValue interface{}, _ error) {
valueArgs = map[string]interface{}{
"opInfo": opInfo,
"inputValue": inputValue,
}
return "fakeOutputValue", errors.New("fakeValueErrMsg")
},
},
OpInfo: OpInfo{
Method: "fakeMethod",
DriverName: "fakeDriverName",
},
}
err := wrapper.Scan("fakeDbValue")
tt.AssertErrContains(t, err, "fakeScanErrMsg")
tt.AssertEqual(t, scanArgs, map[string]interface{}{
"opInfo": OpInfo{
Method: "fakeMethod",
DriverName: "fakeDriverName",
},
"attrPtr": "fakeAttr",
"dbValue": "fakeDbValue",
})
value, err := wrapper.Value()
tt.AssertErrContains(t, err, "fakeValueErrMsg")
tt.AssertEqual(t, valueArgs, map[string]interface{}{
"opInfo": OpInfo{
Method: "fakeMethod",
DriverName: "fakeDriverName",
},
"inputValue": "fakeAttr",
})
tt.AssertEqual(t, value, "fakeOutputValue")
}

View File

@ -0,0 +1,45 @@
package modifiers
import (
"testing"
tt "github.com/vingarcia/ksql/internal/testtools"
)
func TestRegisterAttrModifier(t *testing.T) {
t.Run("should register new modifiers correctly", func(t *testing.T) {
modifier1 := AttrModifierMock{}
modifier2 := AttrModifierMock{}
RegisterAttrModifier("fakeModifierName1", &modifier1)
RegisterAttrModifier("fakeModifierName2", &modifier2)
mod, err := LoadGlobalModifier("fakeModifierName1")
tt.AssertNoErr(t, err)
tt.AssertEqual(t, mod, &modifier1)
mod, err = LoadGlobalModifier("fakeModifierName2")
tt.AssertNoErr(t, err)
tt.AssertEqual(t, mod, &modifier2)
})
t.Run("should panic registering a modifier and the name already exists", func(t *testing.T) {
modifier1 := AttrModifierMock{}
modifier2 := AttrModifierMock{}
RegisterAttrModifier("fakeModifierName", &modifier1)
panicPayload := tt.PanicHandler(func() {
RegisterAttrModifier("fakeModifierName", &modifier2)
})
err, ok := panicPayload.(error)
tt.AssertEqual(t, ok, true)
tt.AssertErrContains(t, err, "KSQL", "fakeModifierName", "name is already in use")
})
t.Run("should return an error when loading an inexistent modifier", func(t *testing.T) {
mod, err := LoadGlobalModifier("nonExistentModifier")
tt.AssertErrContains(t, err, "nonExistentModifier")
tt.AssertEqual(t, mod, nil)
})
}

View File

@ -0,0 +1,122 @@
package modifiers
import (
"context"
"testing"
tt "github.com/vingarcia/ksql/internal/testtools"
)
func TestAttrScan(t *testing.T) {
ctx := context.Background()
type FakeAttr struct {
Foo string `json:"foo"`
}
tests := []struct {
desc string
dbInput interface{}
expectedValue interface{}
expectErrToContain []string
}{
{
desc: "should set struct to zero value if input is nil",
dbInput: nil,
expectedValue: FakeAttr{},
},
{
desc: "should work when input is a byte slice",
dbInput: []byte(`{"foo":"bar"}`),
expectedValue: FakeAttr{
Foo: "bar",
},
},
{
desc: "should work when input is a string",
dbInput: `{"foo":"bar"}`,
expectedValue: FakeAttr{
Foo: "bar",
},
},
{
desc: "should report error if input type is unsupported",
dbInput: 10,
expectErrToContain: []string{"unexpected type", "int"},
},
}
for _, test := range tests {
t.Run(test.desc, func(t *testing.T) {
fakeAttr := FakeAttr{
Foo: "notZeroValue",
}
err := jsonModifier{}.AttrScan(ctx, OpInfo{}, &fakeAttr, test.dbInput)
if test.expectErrToContain != nil {
tt.AssertErrContains(t, err, test.expectErrToContain...)
t.Skip()
}
tt.AssertNoErr(t, err)
tt.AssertEqual(t, fakeAttr, test.expectedValue)
})
}
}
func TestAttrValue(t *testing.T) {
ctx := context.Background()
type FakeAttr struct {
Foo string `json:"foo"`
}
tests := []struct {
desc string
dbInput interface{}
opInfoInput OpInfo
attrValue interface{}
expectedOutput interface{}
expectErrToContain []string
}{
{
desc: "should return a byte array when the driver is not sqlserver",
dbInput: []byte(`{"foo":"bar"}`),
opInfoInput: OpInfo{
DriverName: "notSQLServer",
},
attrValue: FakeAttr{
Foo: "bar",
},
expectedOutput: tt.ToJSON(t, map[string]interface{}{
"foo": "bar",
}),
},
{
desc: "should return a string when the driver is sqlserver",
dbInput: []byte(`{"foo":"bar"}`),
opInfoInput: OpInfo{
DriverName: "sqlserver",
},
attrValue: FakeAttr{
Foo: "bar",
},
expectedOutput: string(tt.ToJSON(t, map[string]interface{}{
"foo": "bar",
})),
},
}
for _, test := range tests {
t.Run(test.desc, func(t *testing.T) {
output, err := jsonModifier{}.AttrValue(ctx, test.opInfoInput, test.attrValue)
if test.expectErrToContain != nil {
tt.AssertErrContains(t, err, test.expectErrToContain...)
t.Skip()
}
tt.AssertNoErr(t, err)
tt.AssertEqual(t, output, test.expectedOutput)
})
}
}

View File

@ -0,0 +1,38 @@
package modifiers
import "context"
// AttrModifierMock mocks the modifiers.AttrModifier interface
type AttrModifierMock struct {
AttrScanFn func(
ctx context.Context,
opInfo OpInfo,
attrPtr interface{},
dbValue interface{},
) error
AttrValueFn func(
ctx context.Context,
opInfo OpInfo,
inputValue interface{},
) (outputValue interface{}, _ error)
}
// AttrScan mocks the AttrScan method
func (a AttrModifierMock) AttrScan(
ctx context.Context,
opInfo OpInfo,
attrPtr interface{},
dbValue interface{},
) error {
return a.AttrScanFn(ctx, opInfo, attrPtr, dbValue)
}
// AttrValue mocks the AttrValue method
func (a AttrModifierMock) AttrValue(
ctx context.Context,
opInfo OpInfo,
inputValue interface{},
) (outputValue interface{}, _ error) {
return a.AttrValueFn(ctx, opInfo, inputValue)
}

View File

@ -0,0 +1,13 @@
package tt
import (
"encoding/json"
"testing"
)
func ToJSON(t *testing.T, obj interface{}) []byte {
rawJSON, err := json.Marshal(obj)
AssertNoErr(t, err)
return rawJSON
}