2020-08-06 20:58:47 +03:00
|
|
|
package userdriver_test
|
|
|
|
|
|
|
|
import (
|
|
|
|
"testing"
|
|
|
|
|
2023-04-26 18:16:42 +03:00
|
|
|
"github.com/neilotoole/sq/libsq/core/ioz"
|
|
|
|
|
2020-08-06 20:58:47 +03:00
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
|
|
|
|
"github.com/neilotoole/sq/cli/config"
|
|
|
|
"github.com/neilotoole/sq/drivers/userdriver"
|
2020-08-23 13:42:15 +03:00
|
|
|
"github.com/neilotoole/sq/libsq/core/stringz"
|
2020-08-06 20:58:47 +03:00
|
|
|
"github.com/neilotoole/sq/testh"
|
|
|
|
"github.com/neilotoole/sq/testh/testsrc"
|
|
|
|
)
|
|
|
|
|
|
|
|
func TestDriver(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
|
|
|
|
testCases := []struct {
|
|
|
|
handle string
|
|
|
|
tbl string
|
|
|
|
wantRecs int
|
|
|
|
}{
|
|
|
|
{handle: testsrc.PplUD, tbl: "person", wantRecs: 3},
|
|
|
|
{handle: testsrc.RSSNYTLocalUD, tbl: "item", wantRecs: 45},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, tc := range testCases {
|
|
|
|
tc := tc
|
|
|
|
|
|
|
|
t.Run(tc.handle, func(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
|
2023-04-19 17:08:26 +03:00
|
|
|
th := testh.New(t, testh.OptLongOpen())
|
2020-08-06 20:58:47 +03:00
|
|
|
src := th.Source(tc.handle)
|
|
|
|
|
|
|
|
drvr := th.DriverFor(src)
|
|
|
|
err := drvr.Ping(th.Context, src)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
dbase, err := drvr.Open(th.Context, src)
|
|
|
|
require.NoError(t, err)
|
|
|
|
t.Cleanup(func() { assert.NoError(t, dbase.Close()) })
|
|
|
|
|
2023-06-22 08:48:58 +03:00
|
|
|
srcMeta, err := dbase.SourceMetadata(th.Context, false)
|
2020-08-06 20:58:47 +03:00
|
|
|
require.NoError(t, err)
|
|
|
|
require.True(t, stringz.InSlice(srcMeta.TableNames(), tc.tbl))
|
|
|
|
|
|
|
|
tblMeta, err := dbase.TableMetadata(th.Context, tc.tbl)
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, tc.tbl, tblMeta.Name)
|
|
|
|
|
2023-11-19 03:05:48 +03:00
|
|
|
sink, err := th.QuerySQL(src, nil, "SELECT * FROM "+tc.tbl)
|
2020-08-06 20:58:47 +03:00
|
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, tc.wantRecs, len(sink.Recs))
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestValidateDriverDef_KnownGood(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
|
|
|
|
testCases := []string{testsrc.PathDriverDefPpl, testsrc.PathDriverDefRSS}
|
|
|
|
|
|
|
|
for _, defFile := range testCases {
|
|
|
|
defFile := defFile
|
|
|
|
|
|
|
|
t.Run(defFile, func(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
|
|
|
|
defs := testh.DriverDefsFrom(t, defFile)
|
|
|
|
for _, def := range defs {
|
|
|
|
errs := userdriver.ValidateDriverDef(def)
|
|
|
|
require.Empty(t, errs)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestValidateDriverDef(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
|
|
|
|
testCases := []struct {
|
|
|
|
title string
|
|
|
|
yml string
|
|
|
|
wantErrs int
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
title: "driver name is missing, should return with 1 error",
|
|
|
|
yml: `user_drivers:
|
2023-04-19 17:08:26 +03:00
|
|
|
- driver:
|
2020-08-06 20:58:47 +03:00
|
|
|
genre: xml
|
|
|
|
title: People
|
|
|
|
selector: /people`,
|
|
|
|
wantErrs: 1,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
title: "missing genre, title, selector and tables",
|
|
|
|
yml: `user_drivers:
|
|
|
|
- driver: ppl
|
2023-04-19 17:08:26 +03:00
|
|
|
genre:
|
|
|
|
title:
|
|
|
|
selector:
|
2020-08-06 20:58:47 +03:00
|
|
|
tables:`,
|
|
|
|
wantErrs: 4,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
title: "table name, selector and cols are empty",
|
|
|
|
yml: `user_drivers:
|
|
|
|
- driver: ppl
|
|
|
|
genre: xml
|
|
|
|
title: People
|
|
|
|
selector: /people
|
|
|
|
tables:
|
2023-04-19 17:08:26 +03:00
|
|
|
- table:
|
|
|
|
selector:
|
2020-08-06 20:58:47 +03:00
|
|
|
cols:`,
|
|
|
|
wantErrs: 3,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
title: "table selector is empty, col name is empty",
|
|
|
|
yml: `user_drivers:
|
|
|
|
- driver: ppl
|
|
|
|
genre: xml
|
|
|
|
title: People
|
|
|
|
selector: /people
|
|
|
|
tables:
|
|
|
|
- table: person
|
|
|
|
selector:
|
|
|
|
primary_key:
|
|
|
|
- first_name
|
|
|
|
cols:
|
2023-04-19 17:08:26 +03:00
|
|
|
- col:
|
2020-08-06 20:58:47 +03:00
|
|
|
kind: int
|
|
|
|
- col: first_name
|
|
|
|
selector: ./firstName
|
|
|
|
kind: text`,
|
|
|
|
wantErrs: 2,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
title: "primary key is invalid",
|
|
|
|
yml: `user_drivers:
|
|
|
|
- driver: ppl
|
|
|
|
genre: xml
|
|
|
|
title: People
|
|
|
|
selector: /people
|
|
|
|
tables:
|
|
|
|
- table: person
|
|
|
|
selector: /people/person
|
|
|
|
primary_key:
|
|
|
|
- not_a_col_name
|
|
|
|
cols:
|
|
|
|
- col: person_id
|
|
|
|
kind: int`,
|
|
|
|
wantErrs: 1,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, tc := range testCases {
|
|
|
|
tc := tc
|
|
|
|
|
|
|
|
t.Run(tc.title, func(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
|
|
|
|
defs := defsFromString(t, tc.yml)
|
|
|
|
require.Equal(t, 1, len(defs))
|
|
|
|
def := defs[0]
|
|
|
|
errs := userdriver.ValidateDriverDef(def)
|
|
|
|
require.Equal(t, tc.wantErrs, len(errs),
|
|
|
|
"wanted %d errs but got %d: %v", tc.wantErrs, len(errs), errs)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func defsFromString(t *testing.T, yml string) []*userdriver.DriverDef {
|
|
|
|
ext := &config.Ext{}
|
2023-04-26 18:16:42 +03:00
|
|
|
require.NoError(t, ioz.UnmarshallYAML([]byte(yml), ext))
|
2020-08-06 20:58:47 +03:00
|
|
|
return ext.UserDrivers
|
|
|
|
}
|