mirror of https://github.com/VinGarcia/ksql.git
Add tests to the modifiers package
parent
41f4d5487b
commit
9e94445cdc
|
@ -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")
|
||||||
|
}
|
|
@ -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)
|
||||||
|
})
|
||||||
|
}
|
|
@ -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)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
|
@ -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)
|
||||||
|
}
|
|
@ -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
|
||||||
|
}
|
Loading…
Reference in New Issue