2020-08-06 20:58:47 +03:00
|
|
|
package source_test
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"testing"
|
|
|
|
|
2023-04-16 01:28:51 +03:00
|
|
|
"github.com/neilotoole/sq/drivers/sqlserver"
|
|
|
|
"github.com/neilotoole/sq/drivers/xlsx"
|
|
|
|
|
|
|
|
"github.com/neilotoole/sq/drivers/csv"
|
|
|
|
|
|
|
|
"github.com/neilotoole/sq/testh/tutil"
|
|
|
|
|
2020-08-06 20:58:47 +03:00
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
|
|
|
|
"github.com/neilotoole/sq/drivers/mysql"
|
|
|
|
"github.com/neilotoole/sq/drivers/postgres"
|
|
|
|
"github.com/neilotoole/sq/drivers/sqlite3"
|
|
|
|
"github.com/neilotoole/sq/libsq/source"
|
|
|
|
)
|
|
|
|
|
2023-04-16 01:28:51 +03:00
|
|
|
func TestIsValidGroup(t *testing.T) {
|
|
|
|
testCases := []struct {
|
|
|
|
in string
|
|
|
|
valid bool
|
2020-08-06 20:58:47 +03:00
|
|
|
}{
|
2023-04-16 01:28:51 +03:00
|
|
|
{"", true},
|
|
|
|
{" ", false},
|
|
|
|
{"/", true},
|
|
|
|
{"//", false},
|
|
|
|
{"prod", true},
|
|
|
|
{"/prod", false},
|
|
|
|
{"prod/", false},
|
|
|
|
{"prod/user", true},
|
|
|
|
{"prod/user/", false},
|
|
|
|
{"prod/user/pg", true},
|
|
|
|
{"pr_od", true},
|
2020-08-06 20:58:47 +03:00
|
|
|
}
|
|
|
|
|
2023-04-16 01:28:51 +03:00
|
|
|
for i, tc := range testCases {
|
|
|
|
tc := tc
|
|
|
|
t.Run(tutil.Name(i, tc.in), func(t *testing.T) {
|
|
|
|
gotValid := source.IsValidGroup(tc.in)
|
|
|
|
require.Equal(t, tc.valid, gotValid)
|
|
|
|
})
|
2020-08-06 20:58:47 +03:00
|
|
|
}
|
2023-04-16 01:28:51 +03:00
|
|
|
}
|
2020-08-06 20:58:47 +03:00
|
|
|
|
2023-04-16 01:28:51 +03:00
|
|
|
func TestValidHandle(t *testing.T) {
|
|
|
|
testCases := []struct {
|
|
|
|
in string
|
|
|
|
wantErr bool
|
|
|
|
}{
|
|
|
|
{in: "", wantErr: true},
|
|
|
|
{in: " ", wantErr: true},
|
|
|
|
{in: "handle", wantErr: true},
|
|
|
|
{in: "@", wantErr: true},
|
|
|
|
{in: "1handle", wantErr: true},
|
|
|
|
{in: "@ handle", wantErr: true},
|
|
|
|
{in: "@handle ", wantErr: true},
|
|
|
|
{in: "@handle#", wantErr: true},
|
|
|
|
{in: "@1handle", wantErr: true},
|
|
|
|
{in: "@1", wantErr: true},
|
|
|
|
{in: "@?handle", wantErr: true},
|
|
|
|
{in: "@?handle#", wantErr: true},
|
|
|
|
{in: "@ha\nndle", wantErr: true},
|
|
|
|
{in: "@group/handle"},
|
|
|
|
{in: "@group/sub/sub2/handle"},
|
|
|
|
{in: "@group/handle"},
|
|
|
|
{in: "@group/", wantErr: true},
|
|
|
|
{in: "@group/wub/", wantErr: true},
|
|
|
|
{in: "@handle"},
|
|
|
|
{in: "@handle1"},
|
|
|
|
{in: "@h1"},
|
|
|
|
{in: "@h_"},
|
|
|
|
{in: "@h__1"},
|
|
|
|
{in: "@h__1__a___"},
|
2020-08-06 20:58:47 +03:00
|
|
|
}
|
|
|
|
|
2023-04-16 01:28:51 +03:00
|
|
|
for i, tc := range testCases {
|
|
|
|
tc := tc
|
|
|
|
t.Run(tutil.Name(i, tc.in), func(t *testing.T) {
|
|
|
|
gotErr := source.ValidHandle(tc.in)
|
|
|
|
if tc.wantErr {
|
|
|
|
require.Error(t, gotErr)
|
|
|
|
} else {
|
|
|
|
require.NoError(t, gotErr)
|
|
|
|
}
|
|
|
|
})
|
2020-08-06 20:58:47 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestSuggestHandle(t *testing.T) {
|
|
|
|
testCases := []struct {
|
2023-04-22 06:36:32 +03:00
|
|
|
typ source.DriverType
|
2020-08-06 20:58:47 +03:00
|
|
|
loc string
|
|
|
|
want string
|
|
|
|
taken []string
|
|
|
|
}{
|
2023-04-16 01:28:51 +03:00
|
|
|
{
|
|
|
|
typ: csv.TypeCSV,
|
|
|
|
loc: "/path/to/actor.csv",
|
|
|
|
want: "@actor",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
typ: source.TypeNone,
|
|
|
|
loc: "/path/to/actor.csv",
|
|
|
|
want: "@actor",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
typ: xlsx.Type,
|
|
|
|
loc: "/path/to/sakila.xlsx",
|
|
|
|
want: "@sakila",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
typ: xlsx.Type,
|
|
|
|
loc: "/path/to/123_sakila.xlsx",
|
|
|
|
want: "@h123_sakila",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
typ: xlsx.Type,
|
|
|
|
loc: "/path/to/__sakila.xlsx",
|
|
|
|
want: "@h__sakila",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
typ: xlsx.Type,
|
|
|
|
loc: "/path/to/sakila.something.xlsx",
|
|
|
|
want: "@sakila_something",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
typ: xlsx.Type,
|
|
|
|
loc: "/path/to/😀abc123😀",
|
|
|
|
want: "@h_abc123_",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
typ: source.TypeNone,
|
|
|
|
loc: "/path/to/sakila.xlsx",
|
|
|
|
want: "@sakila",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
typ: xlsx.Type,
|
|
|
|
loc: "/path/to/sakila.xlsx",
|
|
|
|
want: "@sakila2",
|
|
|
|
taken: []string{"@sakila", "@sakila1"},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
typ: sqlite3.Type,
|
|
|
|
loc: "sqlite3:///path/to/sakila.db",
|
|
|
|
want: "@sakila",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
typ: source.TypeNone,
|
|
|
|
loc: "sqlite3:///path/to/sakila.db",
|
|
|
|
want: "@sakila",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
typ: sqlite3.Type,
|
|
|
|
loc: "/path/to/sakila.db",
|
|
|
|
want: "@sakila",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
typ: sqlserver.Type,
|
|
|
|
loc: "sqlserver://sakila_p_ssW0rd@localhost?database=sakila",
|
|
|
|
want: "@sakila",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
typ: source.TypeNone,
|
|
|
|
loc: "sqlserver://sakila_p_ssW0rd@localhost?database=sakila",
|
|
|
|
want: "@sakila",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
typ: source.TypeNone,
|
|
|
|
loc: "sqlserver://sakila_p_ssW0rd@localhost?database=sakila",
|
|
|
|
want: "@sakila2",
|
|
|
|
taken: []string{"@sakila"},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
typ: postgres.Type,
|
|
|
|
loc: "postgres://sakila_p_ssW0rd@localhost/sakila",
|
|
|
|
want: "@sakila",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
typ: source.TypeNone,
|
|
|
|
loc: "postgres://sakila_p_ssW0rd@localhost/sakila",
|
|
|
|
want: "@sakila",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
typ: postgres.Type,
|
|
|
|
loc: "postgres://sakila_p_ssW0rd@localhost/sakila",
|
|
|
|
want: "@sakila",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
typ: mysql.Type,
|
|
|
|
loc: "mysql://sakila_p_ssW0rd@localhost:3306/sakila",
|
|
|
|
want: "@sakila",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
typ: source.TypeNone,
|
|
|
|
loc: "mysql://sakila_p_ssW0rd@localhost:3306/sakila",
|
|
|
|
want: "@sakila",
|
|
|
|
},
|
2020-08-06 20:58:47 +03:00
|
|
|
}
|
|
|
|
|
2023-04-16 01:28:51 +03:00
|
|
|
for i, tc := range testCases {
|
2020-08-06 20:58:47 +03:00
|
|
|
tc := tc
|
2023-04-16 01:28:51 +03:00
|
|
|
t.Run(tutil.Name(i, tc.typ, tc.loc), func(t *testing.T) {
|
2023-04-19 08:28:09 +03:00
|
|
|
set := &source.Collection{}
|
2023-04-16 01:28:51 +03:00
|
|
|
for i := range tc.taken {
|
|
|
|
err := set.Add(&source.Source{
|
|
|
|
Handle: tc.taken[i],
|
|
|
|
Type: sqlite3.Type,
|
|
|
|
Location: "/tmp/taken.db",
|
|
|
|
})
|
|
|
|
require.NoError(t, err)
|
2020-08-06 20:58:47 +03:00
|
|
|
}
|
|
|
|
|
2023-04-16 01:28:51 +03:00
|
|
|
got, err := source.SuggestHandle(set, tc.typ, tc.loc)
|
2020-08-06 20:58:47 +03:00
|
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, tc.want, got)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestParseTableHandle(t *testing.T) {
|
|
|
|
testCases := []struct {
|
|
|
|
input string
|
|
|
|
valid bool
|
|
|
|
handle string
|
|
|
|
table string
|
|
|
|
}{
|
|
|
|
{"@handle1", true, "@handle1", ""},
|
|
|
|
{" @handle1 ", true, "@handle1", ""},
|
|
|
|
{"@handle1.tbl1", true, "@handle1", "tbl1"},
|
|
|
|
{" @handle1.tbl1 ", true, "@handle1", "tbl1"},
|
|
|
|
{"@handle1 .tbl1", false, "", ""},
|
|
|
|
{"@handle1. tbl1", false, "", ""},
|
|
|
|
{"@handle1 . tbl1", false, "", ""},
|
|
|
|
{".tbl1", true, "", "tbl1"},
|
|
|
|
{" .tbl1 ", true, "", "tbl1"},
|
|
|
|
{" ._tbl1 ", true, "", "_tbl1"},
|
|
|
|
{"invalidhandle", false, "", ""},
|
|
|
|
{"invalidhandle.tbl1", false, "", ""},
|
|
|
|
{"invalidhandle.@tbl1", false, "", ""},
|
|
|
|
{".invalid table", false, "", ""},
|
|
|
|
{"", false, "", ""},
|
|
|
|
{" ", false, "", ""},
|
|
|
|
}
|
|
|
|
|
|
|
|
for i, tc := range testCases {
|
|
|
|
tc := tc
|
|
|
|
|
2023-04-02 22:49:45 +03:00
|
|
|
t.Run(fmt.Sprintf("[%d]__%s", i, tc.input), func(t *testing.T) {
|
2020-08-06 20:58:47 +03:00
|
|
|
handle, table, err := source.ParseTableHandle(tc.input)
|
|
|
|
if tc.valid {
|
|
|
|
assert.NoError(t, err)
|
|
|
|
} else {
|
|
|
|
assert.Error(t, err)
|
|
|
|
}
|
|
|
|
assert.Equal(t, tc.handle, handle)
|
|
|
|
assert.Equal(t, tc.table, table)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|