mirror of
https://github.com/neilotoole/sq.git
synced 2024-11-24 11:54:37 +03:00
Linting of _test.go files (#121)
* test linting * test linting * test linting * test linting
This commit is contained in:
parent
f9c19785e3
commit
c778c8ced5
@ -13,7 +13,7 @@ run:
|
||||
# Default: 1m
|
||||
timeout: 5m
|
||||
|
||||
tests: false
|
||||
tests: true
|
||||
|
||||
skip-dirs:
|
||||
# Skip jcolorenc because big chunks of it are copied from
|
||||
|
@ -93,6 +93,8 @@ func TestCreateTblTestBytes(t *testing.T) {
|
||||
// TestOutputRaw verifies that the raw output format works.
|
||||
// We're particularly concerned that bytes output is correct.
|
||||
func TestOutputRaw(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
for _, handle := range sakila.SQLAll() {
|
||||
handle := handle
|
||||
|
||||
|
@ -1,9 +1,10 @@
|
||||
package cli_test
|
||||
|
||||
import (
|
||||
"github.com/neilotoole/sq/testh/tutil"
|
||||
"testing"
|
||||
|
||||
"github.com/neilotoole/sq/testh/tutil"
|
||||
|
||||
"github.com/neilotoole/sq/drivers/csv"
|
||||
"github.com/neilotoole/sq/drivers/mysql"
|
||||
"github.com/neilotoole/sq/drivers/postgres"
|
||||
@ -44,9 +45,12 @@ func TestCmdAdd(t *testing.T) {
|
||||
{loc: proj.Abs(sakila.PathCSVActor), driver: "csv", wantHandle: "@actor_csv", wantType: csv.TypeCSV},
|
||||
{loc: proj.Abs(sakila.PathCSVActor), driver: "xlsx", wantErr: true},
|
||||
// sqlite can be added both with and without the scheme "sqlite://"
|
||||
{loc: "sqlite3://" + proj.Abs(sakila.PathSL3), wantHandle: "@sakila_sqlite", wantType: sqlite3.Type}, // with scheme
|
||||
{loc: proj.Abs(sakila.PathSL3), wantHandle: "@sakila_sqlite", wantType: sqlite3.Type}, // without scheme, abs path
|
||||
{loc: proj.Rel(sakila.PathSL3), wantHandle: "@sakila_sqlite", wantType: sqlite3.Type}, // without scheme, relative path
|
||||
{loc: "sqlite3://" + proj.Abs(sakila.PathSL3), wantHandle: "@sakila_sqlite",
|
||||
wantType: sqlite3.Type}, // with scheme
|
||||
{loc: proj.Abs(sakila.PathSL3), wantHandle: "@sakila_sqlite",
|
||||
wantType: sqlite3.Type}, // without scheme, abs path
|
||||
{loc: proj.Rel(sakila.PathSL3), wantHandle: "@sakila_sqlite",
|
||||
wantType: sqlite3.Type}, // without scheme, relative path
|
||||
{loc: th.Source(sakila.Pg).Location, wantHandle: "@sakila_pg", wantType: postgres.Type},
|
||||
{loc: th.Source(sakila.MS).Location, wantHandle: "@sakila_mssql", wantType: sqlserver.Type},
|
||||
{loc: th.Source(sakila.My).Location, wantHandle: "@sakila_my", wantType: mysql.Type},
|
||||
|
@ -2,10 +2,11 @@ package cli_test
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/neilotoole/sq/testh/tutil"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/neilotoole/sq/testh/tutil"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/neilotoole/sq/drivers/csv"
|
||||
|
@ -126,7 +126,7 @@ func TestCmdSLQ_OutputFlag(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestCmdSLQ_Join(t *testing.T) {
|
||||
const queryTpl = `%s.customer, %s.address | join(.address_id) | .customer_id == %d | .[0] | .customer_id, .email, .city_id`
|
||||
const queryTpl = `%s.customer, %s.address | join(.address_id) | .customer_id == %d | .[0] | .customer_id, .email, .city_id` //nolint:lll
|
||||
handles := sakila.SQLAll()
|
||||
|
||||
// Attempt to join every SQL test source against every SQL test source.
|
||||
|
@ -2,11 +2,12 @@ package cli_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/neilotoole/sq/testh/tutil"
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/neilotoole/sq/testh/tutil"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/neilotoole/sq/drivers/userdriver"
|
||||
@ -64,6 +65,8 @@ func TestCmdSQL_Insert(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestCmdSQL_SelectFromUserDriver(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
testCases := map[string][]struct {
|
||||
tblName string
|
||||
wantRows int
|
||||
@ -100,8 +103,10 @@ func TestCmdSQL_SelectFromUserDriver(t *testing.T) {
|
||||
err := ru.exec("sql", "--csv", "--header=false", "SELECT * FROM "+wantTbl.tblName)
|
||||
require.NoError(t, err)
|
||||
recs := ru.mustReadCSV()
|
||||
require.Equal(t, wantTbl.wantRows, len(recs), "expected %d rows in tbl %q but got %s", wantTbl.wantRows, wantTbl, len(recs))
|
||||
require.Equal(t, wantTbl.wantCols, len(recs[0]), "expected %d cols in tbl %q but got %s", wantTbl.wantCols, wantTbl, len(recs[0]))
|
||||
require.Equal(t, wantTbl.wantRows, len(recs), "expected %d rows in tbl %q but got %s", wantTbl.wantRows,
|
||||
wantTbl, len(recs))
|
||||
require.Equal(t, wantTbl.wantCols, len(recs[0]), "expected %d cols in tbl %q but got %s",
|
||||
wantTbl.wantCols, wantTbl, len(recs[0]))
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -119,8 +124,10 @@ func TestCmdSQL_StdinQuery(t *testing.T) {
|
||||
wantErr bool
|
||||
}{
|
||||
{fpath: proj.Abs(sakila.PathCSVActorNoHeader), tbl: source.MonotableName, wantCount: sakila.TblActorCount},
|
||||
{fpath: proj.Abs(sakila.PathXLSXActorHeader), srcHeader: true, tbl: sakila.TblActor, wantCount: sakila.TblActorCount},
|
||||
{fpath: proj.Abs(sakila.PathXLSXSubset), srcHeader: true, tbl: sakila.TblActor, wantCount: sakila.TblActorCount},
|
||||
{fpath: proj.Abs(sakila.PathXLSXActorHeader), srcHeader: true, tbl: sakila.TblActor,
|
||||
wantCount: sakila.TblActorCount},
|
||||
{fpath: proj.Abs(sakila.PathXLSXSubset), srcHeader: true, tbl: sakila.TblActor,
|
||||
wantCount: sakila.TblActorCount},
|
||||
{fpath: proj.Abs("README.md"), wantErr: true},
|
||||
}
|
||||
|
||||
|
@ -11,6 +11,8 @@ import (
|
||||
)
|
||||
|
||||
func TestCmdTblCopy(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
for _, handle := range sakila.SQLAll() {
|
||||
handle := handle
|
||||
|
||||
@ -26,7 +28,8 @@ func TestCmdTblCopy(t *testing.T) {
|
||||
err := ru1.exec("tbl", "copy", "--data=false", srcTblHandle, src.Handle+"."+destTbl1)
|
||||
require.NoError(t, err)
|
||||
defer th.DropTable(src, destTbl1)
|
||||
require.Equal(t, int64(0), th.RowCount(src, destTbl1), "should not have copied any rows because --data=false")
|
||||
require.Equal(t, int64(0), th.RowCount(src, destTbl1),
|
||||
"should not have copied any rows because --data=false")
|
||||
|
||||
// --data=true
|
||||
ru2 := newRun(t).add(*src)
|
||||
@ -34,12 +37,15 @@ func TestCmdTblCopy(t *testing.T) {
|
||||
err = ru2.exec("tbl", "copy", "--data=true", srcTblHandle, src.Handle+"."+destTbl2)
|
||||
require.NoError(t, err)
|
||||
defer th.DropTable(src, destTbl2)
|
||||
require.Equal(t, int64(sakila.TblActorCount), th.RowCount(src, destTbl2), "should have copied rows because --data=true")
|
||||
require.Equal(t, int64(sakila.TblActorCount), th.RowCount(src, destTbl2),
|
||||
"should have copied rows because --data=true")
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestCmdTblDrop(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
for _, handle := range sakila.SQLAll() {
|
||||
handle := handle
|
||||
|
||||
@ -74,8 +80,9 @@ func TestCmdTblDrop(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestCmdTblTruncate(t *testing.T) {
|
||||
testCases := []string{sakila.MS}
|
||||
t.Parallel()
|
||||
|
||||
testCases := []string{sakila.MS, sakila.My, sakila.Pg9}
|
||||
for _, handle := range testCases {
|
||||
handle := handle
|
||||
|
||||
|
@ -1,11 +1,12 @@
|
||||
package config_test
|
||||
|
||||
import (
|
||||
"github.com/neilotoole/sq/testh/tutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/neilotoole/sq/testh/tutil"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
@ -73,11 +74,12 @@ func TestFileStore_Load(t *testing.T) {
|
||||
for _, match := range good {
|
||||
match := match
|
||||
t.Run(tutil.Name(match), func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
fs.Path = match
|
||||
_, err = fs.Load()
|
||||
require.NoError(t, err, match)
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
for _, match := range bad {
|
||||
|
@ -3,10 +3,11 @@ package output_test
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/neilotoole/sq/testh/tutil"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/neilotoole/sq/testh/tutil"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/neilotoole/sq/cli/output"
|
||||
@ -68,6 +69,8 @@ func TestRecordWriterAdapter(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestRecordWriterAdapter_FlushAfterN(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
const writeRecCount = 200
|
||||
|
||||
testCases := map[int]int{
|
||||
@ -113,6 +116,7 @@ func TestRecordWriterAdapter_FlushAfterN(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
//nolint:tparallel
|
||||
func TestRecordWriterAdapter_FlushAfterDuration(t *testing.T) {
|
||||
// Don't run this as t.Parallel because it's timing sensitive.
|
||||
const (
|
||||
|
@ -32,5 +32,5 @@ func TestDateTimeHandling(t *testing.T) {
|
||||
require.NoError(t, w.Close())
|
||||
|
||||
require.Equal(t, want, buf.String())
|
||||
println(buf.String())
|
||||
t.Log(buf.String())
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
//nolint:lll
|
||||
package internal_test
|
||||
|
||||
import (
|
||||
@ -43,8 +44,10 @@ func TestEncode(t *testing.T) {
|
||||
{name: "map_interface_empty_sorted", pretty: true, sortMap: true, v: map[string]any{}, want: "{}\n"},
|
||||
{name: "map_1_pretty", pretty: true, sortMap: true, v: map[string]any{"one": 1}, want: "{\n \"one\": 1\n}\n"},
|
||||
{name: "map_1_no_pretty", sortMap: true, v: map[string]any{"one": 1}, want: "{\"one\":1}\n"},
|
||||
{name: "map_2_pretty", pretty: true, sortMap: true, v: map[string]any{"one": 1, "two": 2}, want: "{\n \"one\": 1,\n \"two\": 2\n}\n"},
|
||||
{name: "map_2_no_pretty", sortMap: true, v: map[string]any{"one": 1, "two": 2}, want: "{\"one\":1,\"two\":2}\n"},
|
||||
{name: "map_2_pretty", pretty: true, sortMap: true, v: map[string]any{"one": 1, "two": 2},
|
||||
want: "{\n \"one\": 1,\n \"two\": 2\n}\n"},
|
||||
{name: "map_2_no_pretty", sortMap: true, v: map[string]any{"one": 1, "two": 2},
|
||||
want: "{\"one\":1,\"two\":2}\n"},
|
||||
{name: "tinystruct", pretty: true, v: TinyStruct{FBool: true}, want: "{\n \"f_bool\": true\n}\n"},
|
||||
}
|
||||
|
||||
@ -128,8 +131,10 @@ func TestEncode_SmallStruct(t *testing.T) {
|
||||
color bool
|
||||
want string
|
||||
}{
|
||||
{pretty: false, color: false, want: "{\"f_int\":7,\"f_slice\":[64,true],\"f_map\":{\"m_float64\":64.64,\"m_string\":\"hello\"},\"f_tinystruct\":{\"f_bool\":true},\"f_string\":\"hello\"}\n"},
|
||||
{pretty: true, color: false, want: "{\n \"f_int\": 7,\n \"f_slice\": [\n 64,\n true\n ],\n \"f_map\": {\n \"m_float64\": 64.64,\n \"m_string\": \"hello\"\n },\n \"f_tinystruct\": {\n \"f_bool\": true\n },\n \"f_string\": \"hello\"\n}\n"},
|
||||
{pretty: false, color: false,
|
||||
want: "{\"f_int\":7,\"f_slice\":[64,true],\"f_map\":{\"m_float64\":64.64,\"m_string\":\"hello\"},\"f_tinystruct\":{\"f_bool\":true},\"f_string\":\"hello\"}\n"},
|
||||
{pretty: true, color: false,
|
||||
want: "{\n \"f_int\": 7,\n \"f_slice\": [\n 64,\n true\n ],\n \"f_map\": {\n \"m_float64\": 64.64,\n \"m_string\": \"hello\"\n },\n \"f_tinystruct\": {\n \"f_bool\": true\n },\n \"f_string\": \"hello\"\n}\n"},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
@ -177,8 +182,10 @@ func TestEncode_Map_Nested(t *testing.T) {
|
||||
color bool
|
||||
want string
|
||||
}{
|
||||
{pretty: false, want: "{\"m_bool1\":true,\"m_nest1\":{\"m_nest1_bool\":true,\"m_nest2\":{\"m_nest2_bool\":true,\"m_nest3\":{\"m_nest3_bool\":true}}},\"m_string1\":\"hello\"}\n"},
|
||||
{pretty: true, want: "{\n \"m_bool1\": true,\n \"m_nest1\": {\n \"m_nest1_bool\": true,\n \"m_nest2\": {\n \"m_nest2_bool\": true,\n \"m_nest3\": {\n \"m_nest3_bool\": true\n }\n }\n },\n \"m_string1\": \"hello\"\n}\n"},
|
||||
{pretty: false,
|
||||
want: "{\"m_bool1\":true,\"m_nest1\":{\"m_nest1_bool\":true,\"m_nest2\":{\"m_nest2_bool\":true,\"m_nest3\":{\"m_nest3_bool\":true}}},\"m_string1\":\"hello\"}\n"},
|
||||
{pretty: true,
|
||||
want: "{\n \"m_bool1\": true,\n \"m_nest1\": {\n \"m_nest1_bool\": true,\n \"m_nest2\": {\n \"m_nest2_bool\": true,\n \"m_nest3\": {\n \"m_nest3_bool\": true\n }\n }\n },\n \"m_string1\": \"hello\"\n}\n"},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
@ -209,7 +216,7 @@ func TestEncode_Map_Nested(t *testing.T) {
|
||||
// TestEncode_Map_StringNotInterface tests maps with a string key
|
||||
// but the value type is not any.
|
||||
// For example, map[string]bool. This test is necessary because the
|
||||
// encoder has a fast path for map[string]any
|
||||
// encoder has a fast path for map[string]any.
|
||||
func TestEncode_Map_StringNotInterface(t *testing.T) {
|
||||
testCases := []struct {
|
||||
pretty bool
|
||||
@ -224,8 +231,10 @@ func TestEncode_Map_StringNotInterface(t *testing.T) {
|
||||
{pretty: true, sortMap: false, v: map[string]bool{}, want: "{}\n"},
|
||||
{pretty: false, sortMap: true, v: map[string]bool{"one": true}, want: "{\"one\":true}\n"},
|
||||
{pretty: false, sortMap: false, v: map[string]bool{"one": true}, want: "{\"one\":true}\n"},
|
||||
{pretty: false, sortMap: true, v: map[string]bool{"one": true, "two": false}, want: "{\"one\":true,\"two\":false}\n"},
|
||||
{pretty: true, sortMap: true, v: map[string]bool{"one": true, "two": false}, want: "{\n \"one\": true,\n \"two\": false\n}\n"},
|
||||
{pretty: false, sortMap: true, v: map[string]bool{"one": true, "two": false},
|
||||
want: "{\"one\":true,\"two\":false}\n"},
|
||||
{pretty: true, sortMap: true, v: map[string]bool{"one": true, "two": false},
|
||||
want: "{\n \"one\": true,\n \"two\": false\n}\n"},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
@ -270,7 +279,8 @@ func TestEncode_RawMessage(t *testing.T) {
|
||||
{name: "empty", pretty: false, v: jcolorenc.RawMessage(`{}`), want: "{}\n"},
|
||||
{name: "no_pretty", pretty: false, v: raw, want: "{\"one\":1,\"two\":2}\n"},
|
||||
{name: "pretty", pretty: true, v: raw, want: "{\n \"one\": 1,\n \"two\": 2\n}\n"},
|
||||
{name: "pretty_struct", pretty: true, v: RawStruct{FString: "hello", FRaw: raw}, want: "{\n \"f_string\": \"hello\",\n \"f_raw\": {\n \"one\": 1,\n \"two\": 2\n }\n}\n"},
|
||||
{name: "pretty_struct", pretty: true, v: RawStruct{FString: "hello", FRaw: raw},
|
||||
want: "{\n \"f_string\": \"hello\",\n \"f_raw\": {\n \"one\": 1,\n \"two\": 2\n }\n}\n"},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
@ -300,7 +310,7 @@ func TestEncode_RawMessage(t *testing.T) {
|
||||
|
||||
// TestEncode_Map_StringNotInterface tests map[string]json.RawMessage.
|
||||
// This test is necessary because the encoder has a fast path
|
||||
// for map[string]any
|
||||
// for map[string]any.
|
||||
func TestEncode_Map_StringRawMessage(t *testing.T) {
|
||||
raw := jcolorenc.RawMessage(`{"one":1,"two":2}`)
|
||||
|
||||
@ -315,9 +325,12 @@ func TestEncode_Map_StringRawMessage(t *testing.T) {
|
||||
{pretty: false, sortMap: false, v: map[string]jcolorenc.RawMessage{}, want: "{}\n"},
|
||||
{pretty: true, sortMap: true, v: map[string]jcolorenc.RawMessage{}, want: "{}\n"},
|
||||
{pretty: true, sortMap: false, v: map[string]jcolorenc.RawMessage{}, want: "{}\n"},
|
||||
{pretty: false, sortMap: true, v: map[string]jcolorenc.RawMessage{"msg1": raw, "msg2": raw}, want: "{\"msg1\":{\"one\":1,\"two\":2},\"msg2\":{\"one\":1,\"two\":2}}\n"},
|
||||
{pretty: true, sortMap: true, v: map[string]jcolorenc.RawMessage{"msg1": raw, "msg2": raw}, want: "{\n \"msg1\": {\n \"one\": 1,\n \"two\": 2\n },\n \"msg2\": {\n \"one\": 1,\n \"two\": 2\n }\n}\n"},
|
||||
{pretty: true, sortMap: false, v: map[string]jcolorenc.RawMessage{"msg1": raw}, want: "{\n \"msg1\": {\n \"one\": 1,\n \"two\": 2\n }\n}\n"},
|
||||
{pretty: false, sortMap: true, v: map[string]jcolorenc.RawMessage{"msg1": raw, "msg2": raw},
|
||||
want: "{\"msg1\":{\"one\":1,\"two\":2},\"msg2\":{\"one\":1,\"two\":2}}\n"},
|
||||
{pretty: true, sortMap: true, v: map[string]jcolorenc.RawMessage{"msg1": raw, "msg2": raw},
|
||||
want: "{\n \"msg1\": {\n \"one\": 1,\n \"two\": 2\n },\n \"msg2\": {\n \"one\": 1,\n \"two\": 2\n }\n}\n"},
|
||||
{pretty: true, sortMap: false, v: map[string]jcolorenc.RawMessage{"msg1": raw},
|
||||
want: "{\n \"msg1\": {\n \"one\": 1,\n \"two\": 2\n }\n}\n"},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
@ -353,8 +366,10 @@ func TestEncode_BigStruct(t *testing.T) {
|
||||
color bool
|
||||
want string
|
||||
}{
|
||||
{pretty: false, want: "{\"f_int\":-7,\"f_int8\":-8,\"f_int16\":-16,\"f_int32\":-32,\"f_int64\":-64,\"f_uint\":7,\"f_uint8\":8,\"f_uint16\":16,\"f_uint32\":32,\"f_uint64\":64,\"f_float32\":32.32,\"f_float64\":64.64,\"f_bool\":true,\"f_bytes\":\"aGVsbG8=\",\"f_nil\":null,\"f_string\":\"hello\",\"f_map\":{\"m_bool\":true,\"m_int64\":64,\"m_nil\":null,\"m_smallstruct\":{\"f_int\":7,\"f_slice\":[64,true],\"f_map\":{\"m_float64\":64.64,\"m_string\":\"hello\"},\"f_tinystruct\":{\"f_bool\":true},\"f_string\":\"hello\"},\"m_string\":\"hello\"},\"f_smallstruct\":{\"f_int\":7,\"f_slice\":[64,true],\"f_map\":{\"m_float64\":64.64,\"m_string\":\"hello\"},\"f_tinystruct\":{\"f_bool\":true},\"f_string\":\"hello\"},\"f_interface\":\"hello\",\"f_interfaces\":[64,\"hello\",true]}\n"},
|
||||
{pretty: true, want: "{\n \"f_int\": -7,\n \"f_int8\": -8,\n \"f_int16\": -16,\n \"f_int32\": -32,\n \"f_int64\": -64,\n \"f_uint\": 7,\n \"f_uint8\": 8,\n \"f_uint16\": 16,\n \"f_uint32\": 32,\n \"f_uint64\": 64,\n \"f_float32\": 32.32,\n \"f_float64\": 64.64,\n \"f_bool\": true,\n \"f_bytes\": \"aGVsbG8=\",\n \"f_nil\": null,\n \"f_string\": \"hello\",\n \"f_map\": {\n \"m_bool\": true,\n \"m_int64\": 64,\n \"m_nil\": null,\n \"m_smallstruct\": {\n \"f_int\": 7,\n \"f_slice\": [\n 64,\n true\n ],\n \"f_map\": {\n \"m_float64\": 64.64,\n \"m_string\": \"hello\"\n },\n \"f_tinystruct\": {\n \"f_bool\": true\n },\n \"f_string\": \"hello\"\n },\n \"m_string\": \"hello\"\n },\n \"f_smallstruct\": {\n \"f_int\": 7,\n \"f_slice\": [\n 64,\n true\n ],\n \"f_map\": {\n \"m_float64\": 64.64,\n \"m_string\": \"hello\"\n },\n \"f_tinystruct\": {\n \"f_bool\": true\n },\n \"f_string\": \"hello\"\n },\n \"f_interface\": \"hello\",\n \"f_interfaces\": [\n 64,\n \"hello\",\n true\n ]\n}\n"},
|
||||
{pretty: false,
|
||||
want: "{\"f_int\":-7,\"f_int8\":-8,\"f_int16\":-16,\"f_int32\":-32,\"f_int64\":-64,\"f_uint\":7,\"f_uint8\":8,\"f_uint16\":16,\"f_uint32\":32,\"f_uint64\":64,\"f_float32\":32.32,\"f_float64\":64.64,\"f_bool\":true,\"f_bytes\":\"aGVsbG8=\",\"f_nil\":null,\"f_string\":\"hello\",\"f_map\":{\"m_bool\":true,\"m_int64\":64,\"m_nil\":null,\"m_smallstruct\":{\"f_int\":7,\"f_slice\":[64,true],\"f_map\":{\"m_float64\":64.64,\"m_string\":\"hello\"},\"f_tinystruct\":{\"f_bool\":true},\"f_string\":\"hello\"},\"m_string\":\"hello\"},\"f_smallstruct\":{\"f_int\":7,\"f_slice\":[64,true],\"f_map\":{\"m_float64\":64.64,\"m_string\":\"hello\"},\"f_tinystruct\":{\"f_bool\":true},\"f_string\":\"hello\"},\"f_interface\":\"hello\",\"f_interfaces\":[64,\"hello\",true]}\n"},
|
||||
{pretty: true,
|
||||
want: "{\n \"f_int\": -7,\n \"f_int8\": -8,\n \"f_int16\": -16,\n \"f_int32\": -32,\n \"f_int64\": -64,\n \"f_uint\": 7,\n \"f_uint8\": 8,\n \"f_uint16\": 16,\n \"f_uint32\": 32,\n \"f_uint64\": 64,\n \"f_float32\": 32.32,\n \"f_float64\": 64.64,\n \"f_bool\": true,\n \"f_bytes\": \"aGVsbG8=\",\n \"f_nil\": null,\n \"f_string\": \"hello\",\n \"f_map\": {\n \"m_bool\": true,\n \"m_int64\": 64,\n \"m_nil\": null,\n \"m_smallstruct\": {\n \"f_int\": 7,\n \"f_slice\": [\n 64,\n true\n ],\n \"f_map\": {\n \"m_float64\": 64.64,\n \"m_string\": \"hello\"\n },\n \"f_tinystruct\": {\n \"f_bool\": true\n },\n \"f_string\": \"hello\"\n },\n \"m_string\": \"hello\"\n },\n \"f_smallstruct\": {\n \"f_int\": 7,\n \"f_slice\": [\n 64,\n true\n ],\n \"f_map\": {\n \"m_float64\": 64.64,\n \"m_string\": \"hello\"\n },\n \"f_tinystruct\": {\n \"f_bool\": true\n },\n \"f_string\": \"hello\"\n },\n \"f_interface\": \"hello\",\n \"f_interfaces\": [\n 64,\n \"hello\",\n true\n ]\n}\n"},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
|
@ -1,3 +1,4 @@
|
||||
//nolint:lll
|
||||
package jsonw_test
|
||||
|
||||
import (
|
||||
@ -140,7 +141,8 @@ func TestRecordWriters(t *testing.T) {
|
||||
colNames, kinds := fixt.ColNamePerKind(false, false, false)
|
||||
recMeta := testh.NewRecordMeta(colNames, kinds)
|
||||
|
||||
v0, v1, v2, v3, v4, v5, v6, v7, v8 := int64(64), float64(64.64), "10000000000000000.99", true, "hello", time.Unix(0, 0).UTC(), time.Unix(0, 0).UTC(), time.Unix(0, 0).UTC(), []byte("hello")
|
||||
v0, v1, v2, v3, v4, v5, v6, v7, v8 := int64(64), float64(64.64), "10000000000000000.99", true, "hello", time.Unix(0,
|
||||
0).UTC(), time.Unix(0, 0).UTC(), time.Unix(0, 0).UTC(), []byte("hello")
|
||||
|
||||
recs := []sqlz.Record{
|
||||
{&v0, &v1, &v2, &v3, &v4, &v5, &v6, &v7, &v8},
|
||||
|
@ -25,7 +25,8 @@ func TestRecordWriter_TblActor(t *testing.T) {
|
||||
want []byte
|
||||
}{
|
||||
{name: "actor_0", numRecs: 0, want: nil},
|
||||
{name: "actor_3", numRecs: 3, want: []byte("1PENELOPEGUINESS2020-06-11T02:50:54Z2NICKWAHLBERG2020-06-11T02:50:54Z3EDCHASE2020-06-11T02:50:54Z")},
|
||||
{name: "actor_3", numRecs: 3,
|
||||
want: []byte("1PENELOPEGUINESS2020-06-11T02:50:54Z2NICKWAHLBERG2020-06-11T02:50:54Z3EDCHASE2020-06-11T02:50:54Z")}, //nolint:lll
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
|
@ -26,7 +26,8 @@ func TestRecordWriter(t *testing.T) {
|
||||
}{
|
||||
{name: "actor_0", handle: sakila.SL3, tbl: sakila.TblActor, numRecs: 0, fixtPath: "testdata/actor_0_rows.xlsx"},
|
||||
{name: "actor_3", handle: sakila.SL3, tbl: sakila.TblActor, numRecs: 3, fixtPath: "testdata/actor_3_rows.xlsx"},
|
||||
{name: "tbl_types_3", handle: testsrc.MiscDB, tbl: testsrc.TblTypes, numRecs: -1, fixtPath: "testdata/miscdb_tbl_types.xlsx"},
|
||||
{name: "tbl_types_3", handle: testsrc.MiscDB, tbl: testsrc.TblTypes, numRecs: -1,
|
||||
fixtPath: "testdata/miscdb_tbl_types.xlsx"},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
|
@ -1,3 +1,4 @@
|
||||
//nolint:lll
|
||||
package xmlw_test
|
||||
|
||||
import (
|
||||
|
@ -10,6 +10,8 @@ import (
|
||||
)
|
||||
|
||||
func TestSmoke(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
testCases := []string{sakila.CSVActor, sakila.TSVActor, sakila.CSVActorHTTP}
|
||||
|
||||
for _, handle := range testCases {
|
||||
@ -30,8 +32,9 @@ func TestSmoke(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestQuerySQL_Count(t *testing.T) {
|
||||
testCases := []string{sakila.CSVActor, sakila.TSVActor}
|
||||
t.Parallel()
|
||||
|
||||
testCases := []string{sakila.CSVActor, sakila.TSVActor}
|
||||
for _, handle := range testCases {
|
||||
handle := handle
|
||||
|
||||
|
@ -3,13 +3,14 @@ package json_test
|
||||
import (
|
||||
"bytes"
|
||||
stdj "encoding/json"
|
||||
"github.com/neilotoole/sq/testh/tutil"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/neilotoole/sq/testh/tutil"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/neilotoole/sq/drivers/json"
|
||||
@ -125,8 +126,10 @@ func TestScanObjectsInArray(t *testing.T) {
|
||||
m2 = []map[string]any{{"a": float64(1)}, {"a": float64(2)}}
|
||||
m3 = []map[string]any{{"a": float64(1)}, {"a": float64(2)}, {"a": float64(3)}}
|
||||
m4 = []map[string]any{
|
||||
{"a": float64(1), "b": []any{float64(1), float64(2), float64(3)}, "c": map[string]any{"c1": float64(1)}, "d": "d1"},
|
||||
{"a": float64(2), "b": []any{float64(21), float64(22), float64(23)}, "c": map[string]any{"c1": float64(2)}, "d": "d2"},
|
||||
{"a": float64(1), "b": []any{float64(1), float64(2), float64(3)}, "c": map[string]any{"c1": float64(1)},
|
||||
"d": "d1"},
|
||||
{"a": float64(2), "b": []any{float64(21), float64(22), float64(23)}, "c": map[string]any{"c1": float64(2)},
|
||||
"d": "d2"},
|
||||
}
|
||||
)
|
||||
|
||||
@ -163,8 +166,11 @@ func TestScanObjectsInArray(t *testing.T) {
|
||||
{in: `[ { "a" : 1} , {"a": 2 } ]`, wantObjs: m2, wantChunks: []string{`{ "a" : 1}`, `{"a": 2 }`}},
|
||||
{in: `[{"a":1},{"a":2},{"a":3}]`, wantObjs: m3, wantChunks: []string{`{"a":1}`, `{"a":2}`, `{"a":3}`}},
|
||||
{in: `[{"a":1} ,{"a":2},{"a":3}]`, wantObjs: m3, wantChunks: []string{`{"a":1}`, `{"a":2}`, `{"a":3}`}},
|
||||
{in: "[\n {\"a\" : 1},\n {\"a\" : 2 \n}\n,\n {\"a\": 3}\n]\n\n", wantObjs: m3, wantChunks: []string{"{\"a\" : 1}", "{\"a\" : 2 \n}", "{\"a\": 3}"}},
|
||||
{in: `[{"a":1,"b":[1,2,3],"c":{"c1":1},"d":"d1"} , {"a":2,"b":[21,22,23],"c":{"c1":2},"d":"d2"}]`, wantObjs: m4, wantChunks: []string{`{"a":1,"b":[1,2,3],"c":{"c1":1},"d":"d1"}`, `{"a":2,"b":[21,22,23],"c":{"c1":2},"d":"d2"}`}},
|
||||
{in: "[\n {\"a\" : 1},\n {\"a\" : 2 \n}\n,\n {\"a\": 3}\n]\n\n", wantObjs: m3,
|
||||
wantChunks: []string{"{\"a\" : 1}", "{\"a\" : 2 \n}", "{\"a\": 3}"}},
|
||||
{in: `[{"a":1,"b":[1,2,3],"c":{"c1":1},"d":"d1"} , {"a":2,"b":[21,22,23],"c":{"c1":2},"d":"d2"}]`,
|
||||
wantObjs: m4, wantChunks: []string{`{"a":1,"b":[1,2,3],"c":{"c1":1},"d":"d1"}`,
|
||||
`{"a":2,"b":[21,22,23],"c":{"c1":2},"d":"d2"}`}},
|
||||
}
|
||||
|
||||
for i, tc := range testCases {
|
||||
@ -235,7 +241,8 @@ func TestColumnOrderFlat(t *testing.T) {
|
||||
{in: `{"d": [3,[4,5,[6,7,8]]], "e":9, "fname":[10,11,[12,13]]}`, want: []string{"d", "e", "fname"}},
|
||||
{in: `{"a":1, "b": {"c":2}, "d": 3, "e":4}`, want: []string{"a", "b_c", "d", "e"}},
|
||||
{in: `{"b":1,"a":2}`, want: []string{"b", "a"}},
|
||||
{in: `{"a":1,"b":2,"c":{"c1":3,"c2":4,"c3":{"d1":5,"d2":6},"c5":7},"e":8}`, want: []string{"a", "b", "c_c1", "c_c2", "c_c3_d1", "c_c3_d2", "c_c5", "e"}},
|
||||
{in: `{"a":1,"b":2,"c":{"c1":3,"c2":4,"c3":{"d1":5,"d2":6},"c5":7},"e":8}`,
|
||||
want: []string{"a", "b", "c_c1", "c_c2", "c_c3_d1", "c_c3_d2", "c_c5", "e"}},
|
||||
}
|
||||
|
||||
for i, tc := range testCases {
|
||||
|
@ -15,17 +15,19 @@ import (
|
||||
"github.com/neilotoole/sq/testh/sakila"
|
||||
)
|
||||
|
||||
// export for testing
|
||||
// export for testing.
|
||||
var (
|
||||
ImportJSON = importJSON
|
||||
ImportJSONA = importJSONA
|
||||
ImportJSONL = importJSONL
|
||||
ColumnOrderFlat = columnOrderFlat
|
||||
NewImportJob = newImportJob
|
||||
)
|
||||
|
||||
// NewImportJob is a constructor for the unexported importJob type.
|
||||
// newImportJob is a constructor for the unexported importJob type.
|
||||
// If sampleSize <= 0, a default value is used.
|
||||
func NewImportJob(fromSrc *source.Source, openFn source.FileOpenFunc, destDB driver.Database, sampleSize int, flatten bool) importJob {
|
||||
func newImportJob(fromSrc *source.Source, openFn source.FileOpenFunc, destDB driver.Database, sampleSize int,
|
||||
flatten bool) importJob {
|
||||
if sampleSize <= 0 {
|
||||
sampleSize = driver.Tuning.SampleSize
|
||||
}
|
||||
|
@ -2,13 +2,13 @@ package json_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/neilotoole/sq/testh/tutil"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/neilotoole/sq/testh/tutil"
|
||||
|
||||
"github.com/neilotoole/lg/testlg"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
@ -17,7 +17,7 @@ import (
|
||||
)
|
||||
|
||||
func TestTypeDetectorFuncs(t *testing.T) {
|
||||
detectFns := map[source.Type]source.TypeDetectFunc{
|
||||
detectFns := map[source.Type]source.TypeDetectFunc{ //nolint:exhaustive
|
||||
json.TypeJSON: json.DetectJSON,
|
||||
json.TypeJSONA: json.DetectJSONA,
|
||||
json.TypeJSONL: json.DetectJSONL,
|
||||
@ -112,15 +112,3 @@ func TestTypeDetectorFuncs(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestDriver(t *testing.T) { // FIXME: delete
|
||||
p := json.Provider{
|
||||
Log: nil,
|
||||
Scratcher: nil,
|
||||
Files: nil,
|
||||
}
|
||||
|
||||
drvr, err := p.DriverFor("json")
|
||||
require.NoError(t, err)
|
||||
fmt.Println(drvr.DriverMetadata())
|
||||
}
|
||||
|
@ -2,11 +2,12 @@ package mysql_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/neilotoole/sq/testh/tutil"
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/neilotoole/sq/testh/tutil"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/neilotoole/sq/cli/output"
|
||||
@ -351,7 +352,8 @@ func TestDatabaseTypes(t *testing.T) {
|
||||
|
||||
sink := &testh.RecordSink{}
|
||||
recw := output.NewRecordWriterAdapter(sink)
|
||||
err := libsq.QuerySQL(th.Context, th.Log, th.Open(src), recw, fmt.Sprintf("SELECT * FROM %s", actualTblName))
|
||||
err := libsq.QuerySQL(th.Context, th.Log, th.Open(src), recw,
|
||||
fmt.Sprintf("SELECT * FROM %s", actualTblName))
|
||||
require.NoError(t, err)
|
||||
written, err := recw.Wait()
|
||||
require.NoError(t, err)
|
||||
@ -365,7 +367,7 @@ func TestDatabaseTypes(t *testing.T) {
|
||||
// TestDatabaseTypeJSON explicitly tests the JSON type
|
||||
// introduced in MySQL v5.7.8.
|
||||
func TestDatabaseTypeJSON(t *testing.T) {
|
||||
// t.Parallel()
|
||||
t.Parallel()
|
||||
|
||||
const (
|
||||
canonicalTblName = "type_test_json"
|
||||
|
@ -1,9 +1,11 @@
|
||||
//nolint:lll
|
||||
package mysql
|
||||
|
||||
import (
|
||||
"github.com/neilotoole/sq/testh/tutil"
|
||||
"testing"
|
||||
|
||||
"github.com/neilotoole/sq/testh/tutil"
|
||||
|
||||
"github.com/go-sql-driver/mysql"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
|
@ -65,6 +65,8 @@ func TestKindFromDBTypeName(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDatabase_SourceMetadata(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
for _, handle := range sakila.MyAll() {
|
||||
handle := handle
|
||||
|
||||
@ -86,6 +88,8 @@ func TestDatabase_SourceMetadata(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDatabase_TableMetadata(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
for _, handle := range sakila.MyAll() {
|
||||
handle := handle
|
||||
|
||||
|
@ -436,6 +436,8 @@ func createTypeTestTable(th *testh.Helper, src *source.Source, withData bool) (r
|
||||
// the returned data matches the inserted data, including verifying
|
||||
// that NULL is handled correctly.
|
||||
func TestDatabaseTypes(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
testCases := sakila.PgAll()
|
||||
for _, handle := range testCases {
|
||||
handle := handle
|
||||
@ -450,7 +452,8 @@ func TestDatabaseTypes(t *testing.T) {
|
||||
|
||||
sink := &testh.RecordSink{}
|
||||
recw := output.NewRecordWriterAdapter(sink)
|
||||
err := libsq.QuerySQL(th.Context, th.Log, th.Open(src), recw, fmt.Sprintf("SELECT * FROM %s", actualTblName))
|
||||
err := libsq.QuerySQL(th.Context, th.Log, th.Open(src), recw,
|
||||
fmt.Sprintf("SELECT * FROM %s", actualTblName))
|
||||
require.NoError(t, err)
|
||||
written, err := recw.Wait()
|
||||
require.NoError(t, err)
|
||||
|
@ -64,7 +64,8 @@ LIMIT 1`
|
||||
|
||||
for i, colType := range colTypes {
|
||||
nullable, ok := colType.Nullable()
|
||||
t.Logf("%d: %s %s %s nullable,ok={%v,%v}", i, colType.Name(), colType.DatabaseTypeName(), colType.ScanType().Name(), nullable, ok)
|
||||
t.Logf("%d: %s %s %s nullable,ok={%v,%v}", i, colType.Name(), colType.DatabaseTypeName(),
|
||||
colType.ScanType().Name(), nullable, ok)
|
||||
|
||||
if !nullable {
|
||||
scanType := colType.ScanType()
|
||||
@ -116,7 +117,8 @@ func Test_VerifyDriverDoesNotReportNullability(t *testing.T) {
|
||||
|
||||
// The col is indicated as nullable via its name/suffix
|
||||
nullable, hasNullable := colType.Nullable()
|
||||
require.False(t, hasNullable, "ColumnType.hasNullable is unfortunately expected to be false for %q", colName)
|
||||
require.False(t, hasNullable, "ColumnType.hasNullable is unfortunately expected to be false for %q",
|
||||
colName)
|
||||
require.False(t, nullable, "ColumnType.nullable is unfortunately expected to be false for %q", colName)
|
||||
}
|
||||
|
||||
|
@ -2,11 +2,12 @@ package sqlite3_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/neilotoole/sq/testh/tutil"
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/neilotoole/sq/testh/tutil"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/neilotoole/sq/cli/output"
|
||||
@ -122,6 +123,8 @@ var typeTestVals = [][]any{
|
||||
// returning the actual table names used. If withData is true, the
|
||||
// test data is also loaded. It is the caller's responsibility to drop
|
||||
// the created tables.
|
||||
//
|
||||
//nolint:unparam // withData is currently unused
|
||||
func createTypeTestTbls(th *testh.Helper, src *source.Source, nTimes int, withData bool) (tblNames []string) {
|
||||
const canonicalTblName = "type_test"
|
||||
const insertTpl = "INSERT INTO %s (%s) VALUES %s"
|
||||
|
@ -76,16 +76,21 @@ func TestRecordMetadata(t *testing.T) {
|
||||
colsMeta []*source.ColMetadata
|
||||
}{
|
||||
{
|
||||
tbl: sakila.TblActor,
|
||||
rowCount: sakila.TblActorCount,
|
||||
colNames: sakila.TblActorCols(),
|
||||
colKinds: []kind.Kind{kind.Int, kind.Text, kind.Text, kind.Datetime},
|
||||
scanTypes: []reflect.Type{sqlz.RTypeNullInt64, sqlz.RTypeNullString, sqlz.RTypeNullString, sqlz.RTypeNullTime},
|
||||
tbl: sakila.TblActor,
|
||||
rowCount: sakila.TblActorCount,
|
||||
colNames: sakila.TblActorCols(),
|
||||
colKinds: []kind.Kind{kind.Int, kind.Text, kind.Text, kind.Datetime},
|
||||
scanTypes: []reflect.Type{sqlz.RTypeNullInt64, sqlz.RTypeNullString, sqlz.RTypeNullString,
|
||||
sqlz.RTypeNullTime},
|
||||
colsMeta: []*source.ColMetadata{
|
||||
{Name: "actor_id", Position: 0, PrimaryKey: true, BaseType: "INTEGER", ColumnType: "INTEGER", Kind: kind.Int, Nullable: false},
|
||||
{Name: "first_name", Position: 1, BaseType: "VARCHAR(45)", ColumnType: "VARCHAR(45)", Kind: kind.Text, Nullable: false},
|
||||
{Name: "last_name", Position: 2, BaseType: "VARCHAR(45)", ColumnType: "VARCHAR(45)", Kind: kind.Text, Nullable: false},
|
||||
{Name: "last_update", Position: 3, BaseType: "TIMESTAMP", ColumnType: "TIMESTAMP", Kind: kind.Datetime, Nullable: false, DefaultValue: "CURRENT_TIMESTAMP"},
|
||||
{Name: "actor_id", Position: 0, PrimaryKey: true, BaseType: "INTEGER", ColumnType: "INTEGER",
|
||||
Kind: kind.Int, Nullable: false},
|
||||
{Name: "first_name", Position: 1, BaseType: "VARCHAR(45)", ColumnType: "VARCHAR(45)", Kind: kind.Text,
|
||||
Nullable: false},
|
||||
{Name: "last_name", Position: 2, BaseType: "VARCHAR(45)", ColumnType: "VARCHAR(45)", Kind: kind.Text,
|
||||
Nullable: false},
|
||||
{Name: "last_update", Position: 3, BaseType: "TIMESTAMP", ColumnType: "TIMESTAMP", Kind: kind.Datetime,
|
||||
Nullable: false, DefaultValue: "CURRENT_TIMESTAMP"},
|
||||
},
|
||||
},
|
||||
{
|
||||
@ -95,25 +100,35 @@ func TestRecordMetadata(t *testing.T) {
|
||||
colKinds: []kind.Kind{kind.Int, kind.Int, kind.Datetime},
|
||||
scanTypes: []reflect.Type{sqlz.RTypeNullInt64, sqlz.RTypeNullInt64, sqlz.RTypeNullTime},
|
||||
colsMeta: []*source.ColMetadata{
|
||||
{Name: "actor_id", Position: 0, PrimaryKey: true, BaseType: "INT", ColumnType: "INT", Kind: kind.Int, Nullable: false},
|
||||
{Name: "film_id", Position: 1, PrimaryKey: true, BaseType: "INT", ColumnType: "INT", Kind: kind.Int, Nullable: false},
|
||||
{Name: "last_update", Position: 2, BaseType: "TIMESTAMP", ColumnType: "TIMESTAMP", Kind: kind.Datetime, Nullable: false},
|
||||
{Name: "actor_id", Position: 0, PrimaryKey: true, BaseType: "INT", ColumnType: "INT", Kind: kind.Int,
|
||||
Nullable: false},
|
||||
{Name: "film_id", Position: 1, PrimaryKey: true, BaseType: "INT", ColumnType: "INT", Kind: kind.Int,
|
||||
Nullable: false},
|
||||
{Name: "last_update", Position: 2, BaseType: "TIMESTAMP", ColumnType: "TIMESTAMP", Kind: kind.Datetime,
|
||||
Nullable: false},
|
||||
},
|
||||
},
|
||||
{
|
||||
tbl: sakila.TblPayment,
|
||||
rowCount: sakila.TblPaymentCount,
|
||||
colNames: sakila.TblPaymentCols(),
|
||||
colKinds: []kind.Kind{kind.Int, kind.Int, kind.Int, kind.Int, kind.Decimal, kind.Datetime, kind.Datetime},
|
||||
scanTypes: []reflect.Type{sqlz.RTypeNullInt64, sqlz.RTypeNullInt64, sqlz.RTypeNullInt64, sqlz.RTypeNullInt64, sqlz.RTypeNullString, sqlz.RTypeNullTime, sqlz.RTypeNullTime},
|
||||
tbl: sakila.TblPayment,
|
||||
rowCount: sakila.TblPaymentCount,
|
||||
colNames: sakila.TblPaymentCols(),
|
||||
colKinds: []kind.Kind{kind.Int, kind.Int, kind.Int, kind.Int, kind.Decimal, kind.Datetime, kind.Datetime},
|
||||
scanTypes: []reflect.Type{sqlz.RTypeNullInt64, sqlz.RTypeNullInt64, sqlz.RTypeNullInt64,
|
||||
sqlz.RTypeNullInt64, sqlz.RTypeNullString, sqlz.RTypeNullTime, sqlz.RTypeNullTime},
|
||||
colsMeta: []*source.ColMetadata{
|
||||
{Name: "payment_id", Position: 0, PrimaryKey: true, BaseType: "INT", ColumnType: "INT", Kind: kind.Int, Nullable: false},
|
||||
{Name: "payment_id", Position: 0, PrimaryKey: true, BaseType: "INT", ColumnType: "INT", Kind: kind.Int,
|
||||
Nullable: false},
|
||||
{Name: "customer_id", Position: 1, BaseType: "INT", ColumnType: "INT", Kind: kind.Int, Nullable: false},
|
||||
{Name: "staff_id", Position: 2, BaseType: "SMALLINT", ColumnType: "SMALLINT", Kind: kind.Int, Nullable: false},
|
||||
{Name: "rental_id", Position: 3, BaseType: "INT", ColumnType: "INT", Kind: kind.Int, Nullable: true, DefaultValue: "NULL"},
|
||||
{Name: "amount", Position: 4, BaseType: "DECIMAL(5,2)", ColumnType: "DECIMAL(5,2)", Kind: kind.Decimal, Nullable: false},
|
||||
{Name: "payment_date", Position: 5, BaseType: "TIMESTAMP", ColumnType: "TIMESTAMP", Kind: kind.Datetime, Nullable: false},
|
||||
{Name: "last_update", Position: 6, BaseType: "TIMESTAMP", ColumnType: "TIMESTAMP", Kind: kind.Datetime, Nullable: false},
|
||||
{Name: "staff_id", Position: 2, BaseType: "SMALLINT", ColumnType: "SMALLINT", Kind: kind.Int,
|
||||
Nullable: false},
|
||||
{Name: "rental_id", Position: 3, BaseType: "INT", ColumnType: "INT", Kind: kind.Int, Nullable: true,
|
||||
DefaultValue: "NULL"},
|
||||
{Name: "amount", Position: 4, BaseType: "DECIMAL(5,2)", ColumnType: "DECIMAL(5,2)", Kind: kind.Decimal,
|
||||
Nullable: false},
|
||||
{Name: "payment_date", Position: 5, BaseType: "TIMESTAMP", ColumnType: "TIMESTAMP", Kind: kind.Datetime,
|
||||
Nullable: false},
|
||||
{Name: "last_update", Position: 6, BaseType: "TIMESTAMP", ColumnType: "TIMESTAMP", Kind: kind.Datetime,
|
||||
Nullable: false},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -54,7 +54,8 @@ func TestDriverBehavior(t *testing.T) {
|
||||
|
||||
for i, colType := range colTypes {
|
||||
nullable, ok := colType.Nullable()
|
||||
t.Logf("%d: %s %s %s nullable,ok={%v,%v}", i, colType.Name(), colType.DatabaseTypeName(), colType.ScanType().Name(), nullable, ok)
|
||||
t.Logf("%d: %s %s %s nullable,ok={%v,%v}", i, colType.Name(), colType.DatabaseTypeName(),
|
||||
colType.ScanType().Name(), nullable, ok)
|
||||
|
||||
if !nullable {
|
||||
scanType := colType.ScanType()
|
||||
|
@ -2,9 +2,10 @@ package xmlud_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"github.com/neilotoole/sq/testh/tutil"
|
||||
"testing"
|
||||
|
||||
"github.com/neilotoole/sq/testh/tutil"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"gopkg.in/yaml.v2"
|
||||
@ -114,7 +115,8 @@ func TestImport_RSS(t *testing.T) {
|
||||
sink, err = th.QuerySQL(scratchDB.Source(), "SELECT * FROM item")
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 45, len(sink.Recs))
|
||||
require.EqualValues(t, "Trilobites: Fishing for Clues to Solve Namibia’s Fairy Circle Mystery", tutil.Val(sink.Recs[17][4]))
|
||||
require.EqualValues(t, "Trilobites: Fishing for Clues to Solve Namibia’s Fairy Circle Mystery",
|
||||
tutil.Val(sink.Recs[17][4]))
|
||||
for i, rec := range sink.Recs {
|
||||
// Verify that the primary id cols are sequential
|
||||
require.Equal(t, int64(i+1), tutil.Val(rec[0]))
|
||||
|
@ -1,9 +1,10 @@
|
||||
package xlsx_test
|
||||
|
||||
import (
|
||||
"github.com/neilotoole/sq/testh/tutil"
|
||||
"testing"
|
||||
|
||||
"github.com/neilotoole/sq/testh/tutil"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/neilotoole/sq/drivers/xlsx"
|
||||
|
@ -35,7 +35,7 @@ func TestNodesWithType(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestAvg(t *testing.T) {
|
||||
const input = `@mydb1 | .user, .address | join(.user.uid == .address.uid) | .uid, .username, .country | .[0:2] | avg(.uid)`
|
||||
const input = `@mydb1 | .user, .address | join(.user.uid == .address.uid) | .uid, .username, .country | .[0:2] | avg(.uid)` //nolint:lll
|
||||
ast := mustBuildAST(t, input)
|
||||
require.NotNil(t, ast)
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ func buildInitialAST(t *testing.T, input string) (*AST, error) {
|
||||
log := testlg.New(t).Strict(true)
|
||||
|
||||
p := getSLQParser(input)
|
||||
q := p.Query().(*slq.QueryContext)
|
||||
q, _ := p.Query().(*slq.QueryContext)
|
||||
v := &parseTreeVisitor{log: log}
|
||||
err := q.Accept(v)
|
||||
if err != nil {
|
||||
|
@ -29,7 +29,7 @@ func TestRowRange2(t *testing.T) {
|
||||
assert.Equal(t, 1, ins.CountNodes(typeRowRange))
|
||||
nodes := ins.FindNodes(typeRowRange)
|
||||
assert.Equal(t, 1, len(nodes))
|
||||
rr := nodes[0].(*RowRange)
|
||||
rr, _ := nodes[0].(*RowRange)
|
||||
assert.Equal(t, 2, rr.Offset)
|
||||
assert.Equal(t, 1, rr.Limit)
|
||||
}
|
||||
@ -39,7 +39,7 @@ func TestRowRange3(t *testing.T) {
|
||||
|
||||
ast := mustBuildAST(t, fixtRowRange3)
|
||||
ins := NewInspector(log, ast)
|
||||
rr := ins.FindNodes(typeRowRange)[0].(*RowRange)
|
||||
rr, _ := ins.FindNodes(typeRowRange)[0].(*RowRange)
|
||||
assert.Equal(t, 1, rr.Offset)
|
||||
assert.Equal(t, 2, rr.Limit)
|
||||
}
|
||||
@ -49,7 +49,7 @@ func TestRowRange4(t *testing.T) {
|
||||
|
||||
ast := mustBuildAST(t, fixtRowRange4)
|
||||
ins := NewInspector(log, ast)
|
||||
rr := ins.FindNodes(typeRowRange)[0].(*RowRange)
|
||||
rr, _ := ins.FindNodes(typeRowRange)[0].(*RowRange)
|
||||
assert.Equal(t, 0, rr.Offset)
|
||||
assert.Equal(t, 3, rr.Limit)
|
||||
}
|
||||
@ -58,7 +58,7 @@ func TestRowRange5(t *testing.T) {
|
||||
log := testlg.New(t).Strict(true)
|
||||
ast := mustBuildAST(t, fixtRowRange5)
|
||||
ins := NewInspector(log, ast)
|
||||
rr := ins.FindNodes(typeRowRange)[0].(*RowRange)
|
||||
rr, _ := ins.FindNodes(typeRowRange)[0].(*RowRange)
|
||||
assert.Equal(t, 0, rr.Offset)
|
||||
assert.Equal(t, 3, rr.Limit)
|
||||
}
|
||||
@ -67,7 +67,7 @@ func TestRowRange6(t *testing.T) {
|
||||
log := testlg.New(t).Strict(true)
|
||||
ast := mustBuildAST(t, fixtRowRange6)
|
||||
ins := NewInspector(log, ast)
|
||||
rr := ins.FindNodes(typeRowRange)[0].(*RowRange)
|
||||
rr, _ := ins.FindNodes(typeRowRange)[0].(*RowRange)
|
||||
assert.Equal(t, 2, rr.Offset)
|
||||
assert.Equal(t, -1, rr.Limit)
|
||||
}
|
||||
|
@ -10,19 +10,17 @@ import (
|
||||
)
|
||||
|
||||
func TestIs(t *testing.T) {
|
||||
var err error
|
||||
err = errz.Wrap(sql.ErrNoRows, "wrap")
|
||||
err := errz.Wrap(sql.ErrNoRows, "wrap")
|
||||
|
||||
require.Equal(t, "wrap: "+sql.ErrNoRows.Error(), err.Error())
|
||||
require.True(t, errors.Is(err, sql.ErrNoRows))
|
||||
}
|
||||
|
||||
func TestAs(t *testing.T) {
|
||||
var originalErr error
|
||||
var originalErr error //nolint:gosimple
|
||||
originalErr = &CustomError{msg: "huzzah"}
|
||||
|
||||
var err error
|
||||
err = errz.Wrap(errz.Wrap(originalErr, "wrap"), "wrap")
|
||||
err := errz.Wrap(errz.Wrap(originalErr, "wrap"), "wrap")
|
||||
require.Equal(t, "wrap: wrap: huzzah", err.Error())
|
||||
|
||||
var gotCustomErr *CustomError
|
||||
@ -30,7 +28,7 @@ func TestAs(t *testing.T) {
|
||||
require.Equal(t, "huzzah", gotCustomErr.msg)
|
||||
|
||||
gotUnwrap := errz.Cause(err)
|
||||
require.Equal(t, *originalErr.(*CustomError), *gotUnwrap.(*CustomError))
|
||||
require.Equal(t, *originalErr.(*CustomError), *gotUnwrap.(*CustomError)) //nolint:errorlint
|
||||
}
|
||||
|
||||
type CustomError struct {
|
||||
|
@ -145,7 +145,7 @@ func TestKindDetector(t *testing.T) {
|
||||
return
|
||||
}
|
||||
|
||||
require.Equal(t, tc.want.String(), gotKind.String(), tc.in)
|
||||
require.Equal(t, tc.want.String(), gotKind.String())
|
||||
|
||||
if !tc.wantMunge {
|
||||
require.Nil(t, gotMungeFn)
|
||||
|
@ -51,7 +51,9 @@ func TestNullBool_Scan(t *testing.T) {
|
||||
}
|
||||
|
||||
require.Nil(t, err, "[%d] %q: did not expect error: %v", i, tt.input, err)
|
||||
require.Equal(t, tt.expectValid, nb.Valid, "[%d] %q: expected Valid to be %v but got %v", i, tt.input, tt.expectValid, nb.Valid)
|
||||
require.Equal(t, tt.expectBool, nb.Bool, "[%d] %q: expected Bool to be %v but got %v", i, tt.input, tt.expectBool, nb.Bool)
|
||||
require.Equal(t, tt.expectValid, nb.Valid, "[%d] %q: expected Valid to be %v but got %v", i, tt.input,
|
||||
tt.expectValid, nb.Valid)
|
||||
require.Equal(t, tt.expectBool, nb.Bool, "[%d] %q: expected Bool to be %v but got %v", i, tt.input,
|
||||
tt.expectBool, nb.Bool)
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,10 @@
|
||||
package driver_test
|
||||
|
||||
import (
|
||||
"github.com/neilotoole/sq/testh/tutil"
|
||||
"testing"
|
||||
|
||||
"github.com/neilotoole/sq/testh/tutil"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
@ -25,6 +26,8 @@ import (
|
||||
)
|
||||
|
||||
func TestDriver_DropTable(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
for _, handle := range sakila.SQLAll() {
|
||||
handle := handle
|
||||
|
||||
@ -47,8 +50,10 @@ func TestDriver_DropTable(t *testing.T) {
|
||||
require.NoError(t, drvr.DropTable(th.Context, db, tblName, false))
|
||||
|
||||
// Check that we get the expected behavior when the table doesn't exist
|
||||
require.NoError(t, drvr.DropTable(th.Context, db, stringz.UniqSuffix("not_a_table"), true), "should be no error when ifExists is true")
|
||||
require.Error(t, drvr.DropTable(th.Context, db, stringz.UniqSuffix("not_a_table"), false), "error expected when ifExists is false")
|
||||
require.NoError(t, drvr.DropTable(th.Context, db, stringz.UniqSuffix("not_a_table"), true),
|
||||
"should be no error when ifExists is true")
|
||||
require.Error(t, drvr.DropTable(th.Context, db, stringz.UniqSuffix("not_a_table"), false),
|
||||
"error expected when ifExists is false")
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -83,7 +88,8 @@ func TestDriver_CopyTable(t *testing.T) {
|
||||
|
||||
th, src, dbase, drvr := testh.NewWith(t, handle)
|
||||
db := dbase.DB()
|
||||
require.Equal(t, int64(sakila.TblActorCount), th.RowCount(src, sakila.TblActor), "fromTable should have ActorCount rows beforehand")
|
||||
require.Equal(t, int64(sakila.TblActorCount), th.RowCount(src, sakila.TblActor),
|
||||
"fromTable should have ActorCount rows beforehand")
|
||||
|
||||
toTable := stringz.UniqTableName(sakila.TblActor)
|
||||
// First, test with copyData = true
|
||||
|
@ -1,9 +1,10 @@
|
||||
package libsq_test
|
||||
|
||||
import (
|
||||
"github.com/neilotoole/sq/testh/tutil"
|
||||
"testing"
|
||||
|
||||
"github.com/neilotoole/sq/testh/tutil"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/neilotoole/sq/libsq"
|
||||
|
@ -14,7 +14,8 @@ import (
|
||||
// SQL query, that ultimate SQL is returned. Effectively it is
|
||||
// equivalent to libsq.ExecuteSLQ, but without the execution.
|
||||
// Admittedly, this is an ugly workaround.
|
||||
func EngineSLQ2SQL(ctx context.Context, log lg.Log, dbOpener driver.DatabaseOpener, joinDBOpener driver.JoinDatabaseOpener, srcs *source.Set, query string) (targetSQL string, err error) {
|
||||
func EngineSLQ2SQL(ctx context.Context, log lg.Log, dbOpener driver.DatabaseOpener,
|
||||
joinDBOpener driver.JoinDatabaseOpener, srcs *source.Set, query string) (targetSQL string, err error) {
|
||||
var ng *engine
|
||||
ng, err = newEngine(ctx, log, dbOpener, joinDBOpener, srcs, query)
|
||||
if err != nil {
|
||||
|
@ -1,10 +1,11 @@
|
||||
package libsq_test
|
||||
|
||||
import (
|
||||
"github.com/neilotoole/sq/testh/tutil"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/neilotoole/sq/testh/tutil"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/neilotoole/sq/libsq/core/sqlz"
|
||||
@ -80,7 +81,8 @@ func TestQuerySQL_Smoke(t *testing.T) {
|
||||
require.Equal(t, len(tc.fieldTypes), len(sink.Recs[0]))
|
||||
for i := range sink.Recs[0] {
|
||||
require.Equal(t, tc.fieldTypes[i], reflect.TypeOf(sink.Recs[0][i]),
|
||||
"expected field[%d] to have type %s but got %s", i, tc.fieldTypes[i], reflect.TypeOf(sink.Recs[0][i]))
|
||||
"expected field[%d] to have type %s but got %s", i, tc.fieldTypes[i],
|
||||
reflect.TypeOf(sink.Recs[0][i]))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -2,12 +2,13 @@ package source_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/neilotoole/sq/testh/tutil"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/neilotoole/sq/testh/tutil"
|
||||
|
||||
"github.com/neilotoole/errgroup"
|
||||
"github.com/neilotoole/lg/testlg"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
@ -71,13 +71,15 @@ func TestSuggestHandle(t *testing.T) {
|
||||
{typ: xlsx.Type, loc: "/path/to/sakila.something.xlsx", want: "@sakila_something_xlsx"},
|
||||
{typ: xlsx.Type, loc: "/path/to/😀abc123😀", want: "@h_abc123__xlsx"},
|
||||
{typ: source.TypeNone, loc: "/path/to/sakila.xlsx", want: "@sakila_xlsx"},
|
||||
{typ: xlsx.Type, loc: "/path/to/sakila.xlsx", want: "@sakila_xlsx_2", taken: []string{"@sakila_xlsx", "@sakila_xlsx_1"}},
|
||||
{typ: xlsx.Type, loc: "/path/to/sakila.xlsx", want: "@sakila_xlsx_2",
|
||||
taken: []string{"@sakila_xlsx", "@sakila_xlsx_1"}},
|
||||
{typ: sqlite3.Type, loc: "sqlite3:///path/to/sakila.db", want: "@sakila_sqlite"},
|
||||
{typ: source.TypeNone, loc: "sqlite3:///path/to/sakila.db", want: "@sakila_sqlite"},
|
||||
{typ: sqlite3.Type, loc: "/path/to/sakila.db", want: "@sakila_sqlite"},
|
||||
{typ: sqlserver.Type, loc: "sqlserver://sakila_p_ssW0rd@localhost?database=sakila", want: "@sakila_mssql"},
|
||||
{typ: source.TypeNone, loc: "sqlserver://sakila_p_ssW0rd@localhost?database=sakila", want: "@sakila_mssql"},
|
||||
{typ: source.TypeNone, loc: "sqlserver://sakila_p_ssW0rd@localhost?database=sakila", want: "@sakila_mssql_1", taken: []string{"@sakila_mssql"}},
|
||||
{typ: source.TypeNone, loc: "sqlserver://sakila_p_ssW0rd@localhost?database=sakila", want: "@sakila_mssql_1",
|
||||
taken: []string{"@sakila_mssql"}},
|
||||
{typ: postgres.Type, loc: "postgres://sakila_p_ssW0rd@localhost/sakila?sslmode=disable", want: "@sakila_pg"},
|
||||
{typ: source.TypeNone, loc: "postgres://sakila_p_ssW0rd@localhost/sakila?sslmode=disable", want: "@sakila_pg"},
|
||||
{typ: postgres.Type, loc: "postgres://sakila_p_ssW0rd@localhost/sakila?sslmode=disable", want: "@sakila_pg"},
|
||||
|
@ -21,8 +21,6 @@ func TestFiles_Open(t *testing.T) {
|
||||
t.Cleanup(func() { assert.NoError(t, fs.Close()) })
|
||||
|
||||
src1 := &Source{
|
||||
Handle: "@t1",
|
||||
Type: typeXLSX,
|
||||
Location: proj.Abs(testsrc.PathXLSXTestHeader),
|
||||
}
|
||||
|
||||
@ -32,8 +30,6 @@ func TestFiles_Open(t *testing.T) {
|
||||
require.Equal(t, src1.Location, f.Name())
|
||||
|
||||
src2 := &Source{
|
||||
Handle: "@t1",
|
||||
Type: typeCSV,
|
||||
Location: sakila.URLActorCSV,
|
||||
}
|
||||
|
||||
@ -61,21 +57,46 @@ func TestParseLoc(t *testing.T) {
|
||||
{loc: "/path/to/sakila.xlsx", want: parsedLoc{name: "sakila", ext: ".xlsx"}},
|
||||
{loc: "relative/path/to/sakila.xlsx", want: parsedLoc{name: "sakila", ext: ".xlsx"}},
|
||||
{loc: "./relative/path/to/sakila.xlsx", want: parsedLoc{name: "sakila", ext: ".xlsx"}},
|
||||
{loc: "https://server:8080/path/to/sakila.xlsx", want: parsedLoc{scheme: "https", hostname: "server", port: 8080, name: "sakila", ext: ".xlsx"}},
|
||||
{loc: "http://server/path/to/sakila.xlsx?param=val¶m2=val2", want: parsedLoc{scheme: "http", hostname: "server", name: "sakila", ext: ".xlsx"}},
|
||||
{loc: "https://server:8080/path/to/sakila.xlsx",
|
||||
want: parsedLoc{scheme: "https", hostname: "server", port: 8080, name: "sakila", ext: ".xlsx"}},
|
||||
{loc: "http://server/path/to/sakila.xlsx?param=val¶m2=val2",
|
||||
want: parsedLoc{scheme: "http", hostname: "server", name: "sakila", ext: ".xlsx"}},
|
||||
{loc: "sqlite3:/path/to/sakila.db", wantErr: true}, // the scheme is malformed (should be "sqlite3://...")
|
||||
{loc: "sqlite3:///path/to/sakila.sqlite", want: parsedLoc{typ: typeSL3, scheme: "sqlite3", name: "sakila", ext: ".sqlite", dsn: "/path/to/sakila.sqlite"}},
|
||||
{loc: `sqlite3://C:\path\to\sakila.sqlite`, windows: true, want: parsedLoc{typ: typeSL3, scheme: "sqlite3", name: "sakila", ext: ".sqlite", dsn: `C:\path\to\sakila.sqlite`}},
|
||||
{loc: `sqlite3://C:\path\to\sakila.sqlite?param=val`, windows: true, want: parsedLoc{typ: typeSL3, scheme: "sqlite3", name: "sakila", ext: ".sqlite", dsn: `C:\path\to\sakila.sqlite?param=val`}},
|
||||
{loc: "sqlite3:///path/to/sakila", want: parsedLoc{typ: typeSL3, scheme: "sqlite3", name: "sakila", dsn: "/path/to/sakila"}},
|
||||
{loc: "sqlite3://path/to/sakila.db", want: parsedLoc{typ: typeSL3, scheme: "sqlite3", name: "sakila", ext: ".db", dsn: "path/to/sakila.db"}},
|
||||
{loc: "sqlite3:///path/to/sakila.db", want: parsedLoc{typ: typeSL3, scheme: "sqlite3", name: "sakila", ext: ".db", dsn: "/path/to/sakila.db"}},
|
||||
{loc: "sqlserver://sakila:p_ssW0rd@localhost?database=sakila", want: parsedLoc{typ: typeMS, scheme: "sqlserver", user: dbuser, pass: dbpass, hostname: "localhost", name: "sakila", dsn: "Password=p_ssW0rd;Server=localhost;User ID=sakila;database=sakila"}},
|
||||
{loc: "sqlserver://sakila:p_ssW0rd@server:1433?database=sakila", want: parsedLoc{typ: typeMS, scheme: "sqlserver", user: dbuser, pass: dbpass, hostname: "server", port: 1433, name: "sakila", dsn: "Password=p_ssW0rd;Port=1433;Server=server;User ID=sakila;database=sakila"}},
|
||||
{loc: "postgres://sakila:p_ssW0rd@localhost/sakila?sslmode=disable", want: parsedLoc{typ: typePg, scheme: "postgres", user: dbuser, pass: dbpass, hostname: "localhost", name: "sakila", dsn: "dbname=sakila host=localhost password=p_ssW0rd sslmode=disable user=sakila"}},
|
||||
{loc: "postgres://sakila:p_ssW0rd@server:5432/sakila?sslmode=disable", want: parsedLoc{typ: typePg, scheme: "postgres", user: dbuser, pass: dbpass, hostname: "server", port: 5432, name: "sakila", dsn: "dbname=sakila host=server password=p_ssW0rd port=5432 sslmode=disable user=sakila"}},
|
||||
{loc: "mysql://sakila:p_ssW0rd@localhost/sakila", want: parsedLoc{typ: typeMy, scheme: "mysql", user: dbuser, pass: dbpass, hostname: "localhost", name: "sakila", dsn: "sakila:p_ssW0rd@tcp(localhost:3306)/sakila"}},
|
||||
{loc: "mysql://sakila:p_ssW0rd@server:3306/sakila", want: parsedLoc{typ: typeMy, scheme: "mysql", user: dbuser, pass: dbpass, hostname: "server", port: 3306, name: "sakila", dsn: "sakila:p_ssW0rd@tcp(server:3306)/sakila"}},
|
||||
{loc: "sqlite3:///path/to/sakila.sqlite",
|
||||
want: parsedLoc{typ: typeSL3, scheme: "sqlite3", name: "sakila", ext: ".sqlite",
|
||||
dsn: "/path/to/sakila.sqlite"}},
|
||||
{loc: `sqlite3://C:\path\to\sakila.sqlite`, windows: true,
|
||||
want: parsedLoc{typ: typeSL3, scheme: "sqlite3", name: "sakila", ext: ".sqlite",
|
||||
dsn: `C:\path\to\sakila.sqlite`}},
|
||||
{loc: `sqlite3://C:\path\to\sakila.sqlite?param=val`, windows: true,
|
||||
want: parsedLoc{typ: typeSL3, scheme: "sqlite3", name: "sakila", ext: ".sqlite",
|
||||
dsn: `C:\path\to\sakila.sqlite?param=val`}},
|
||||
{loc: "sqlite3:///path/to/sakila",
|
||||
want: parsedLoc{typ: typeSL3, scheme: "sqlite3", name: "sakila", dsn: "/path/to/sakila"}},
|
||||
{loc: "sqlite3://path/to/sakila.db",
|
||||
want: parsedLoc{typ: typeSL3, scheme: "sqlite3", name: "sakila", ext: ".db", dsn: "path/to/sakila.db"}},
|
||||
{loc: "sqlite3:///path/to/sakila.db",
|
||||
want: parsedLoc{typ: typeSL3, scheme: "sqlite3", name: "sakila", ext: ".db", dsn: "/path/to/sakila.db"}},
|
||||
{loc: "sqlserver://sakila:p_ssW0rd@localhost?database=sakila",
|
||||
want: parsedLoc{typ: typeMS, scheme: "sqlserver", user: dbuser, pass: dbpass, hostname: "localhost",
|
||||
name: "sakila", dsn: "Password=p_ssW0rd;Server=localhost;User ID=sakila;database=sakila"}},
|
||||
{loc: "sqlserver://sakila:p_ssW0rd@server:1433?database=sakila",
|
||||
want: parsedLoc{typ: typeMS, scheme: "sqlserver", user: dbuser, pass: dbpass, hostname: "server",
|
||||
port: 1433, name: "sakila",
|
||||
dsn: "Password=p_ssW0rd;Port=1433;Server=server;User ID=sakila;database=sakila"}},
|
||||
{loc: "postgres://sakila:p_ssW0rd@localhost/sakila?sslmode=disable",
|
||||
want: parsedLoc{typ: typePg, scheme: "postgres", user: dbuser, pass: dbpass, hostname: "localhost",
|
||||
name: "sakila", dsn: "dbname=sakila host=localhost password=p_ssW0rd sslmode=disable user=sakila"}},
|
||||
{loc: "postgres://sakila:p_ssW0rd@server:5432/sakila?sslmode=disable",
|
||||
want: parsedLoc{typ: typePg, scheme: "postgres", user: dbuser, pass: dbpass, hostname: "server", port: 5432,
|
||||
name: "sakila",
|
||||
dsn: "dbname=sakila host=server password=p_ssW0rd port=5432 sslmode=disable user=sakila"}},
|
||||
{loc: "mysql://sakila:p_ssW0rd@localhost/sakila",
|
||||
want: parsedLoc{typ: typeMy, scheme: "mysql", user: dbuser, pass: dbpass, hostname: "localhost",
|
||||
name: "sakila", dsn: "sakila:p_ssW0rd@tcp(localhost:3306)/sakila"}},
|
||||
{loc: "mysql://sakila:p_ssW0rd@server:3306/sakila",
|
||||
want: parsedLoc{typ: typeMy, scheme: "mysql", user: dbuser, pass: dbpass, hostname: "server", port: 3306,
|
||||
name: "sakila", dsn: "sakila:p_ssW0rd@tcp(server:3306)/sakila"}},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
|
@ -18,10 +18,14 @@ func TestRedactedLocation(t *testing.T) {
|
||||
{tname: "xlsx", loc: "/path/to/data.xlsx", want: "/path/to/data.xlsx"},
|
||||
{tname: "https", loc: "https://path/to/data.xlsx", want: "https://path/to/data.xlsx"},
|
||||
{tname: "http", loc: "http://path/to/data.xlsx", want: "http://path/to/data.xlsx"},
|
||||
{tname: "sqlserver", loc: "sqlserver://sq:p_ssW0rd@localhost?database=sqtest", want: "sqlserver://sq:****@localhost?database=sqtest"},
|
||||
{tname: "postgres", loc: "postgres://sq:p_ssW0rd@localhost/sqtest?sslmode=disable", want: "postgres://sq:****@localhost/sqtest?sslmode=disable"},
|
||||
{tname: "mysql", loc: "mysql://sq:p_ssW0rd@localhost:3306/sqtest", want: "mysql://sq:****@localhost:3306/sqtest"},
|
||||
{tname: "sqlite3", loc: "sqlite3:///path/to/sqlite.db", want: "sqlite3:/path/to/sqlite.db"}, // FIXME: how many slashes to we want, or zero slashes?
|
||||
{tname: "sqlserver", loc: "sqlserver://sq:p_ssW0rd@localhost?database=sqtest",
|
||||
want: "sqlserver://sq:****@localhost?database=sqtest"},
|
||||
{tname: "postgres", loc: "postgres://sq:p_ssW0rd@localhost/sqtest?sslmode=disable",
|
||||
want: "postgres://sq:****@localhost/sqtest?sslmode=disable"},
|
||||
{tname: "mysql", loc: "mysql://sq:p_ssW0rd@localhost:3306/sqtest",
|
||||
want: "mysql://sq:****@localhost:3306/sqtest"},
|
||||
{tname: "sqlite3", loc: "sqlite3:///path/to/sqlite.db",
|
||||
want: "sqlite3:/path/to/sqlite.db"}, // FIXME: how many slashes to we want, or zero slashes?
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
@ -47,7 +51,8 @@ func TestShortLocation(t *testing.T) {
|
||||
{tname: "https", loc: "https://path/to/data.xlsx", want: "data.xlsx"},
|
||||
{tname: "http", loc: "http://path/to/data.xlsx", want: "data.xlsx"},
|
||||
{tname: "sqlserver", loc: "sqlserver://sq:p_ssw0rd@localhost?database=sqtest", want: "sq@localhost/sqtest"},
|
||||
{tname: "postgres", loc: "postgres://sq:p_ssW0rd@localhost/sqtest?sslmode=disable", want: "sq@localhost/sqtest"},
|
||||
{tname: "postgres", loc: "postgres://sq:p_ssW0rd@localhost/sqtest?sslmode=disable",
|
||||
want: "sq@localhost/sqtest"},
|
||||
{tname: "mysql", loc: "mysql://sq:p_ssW0rd@localhost:3306/sqtest", want: "sq@localhost:3306/sqtest"},
|
||||
{tname: "mysql", loc: "mysql://sq:p_ssW0rd@localhost/sqtest", want: "sq@localhost/sqtest"},
|
||||
}
|
||||
|
@ -1,11 +1,12 @@
|
||||
package testh_test
|
||||
|
||||
import (
|
||||
"github.com/neilotoole/sq/testh/tutil"
|
||||
"io"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/neilotoole/sq/testh/tutil"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"golang.org/x/sync/errgroup"
|
||||
|
||||
@ -149,13 +150,13 @@ func TestHelper_Files(t *testing.T) {
|
||||
|
||||
for i := 0; i < 1000; i++ {
|
||||
g.Go(func() error {
|
||||
r, err := fs.Open(src)
|
||||
require.NoError(t, err)
|
||||
r, fErr := fs.Open(src)
|
||||
require.NoError(t, fErr)
|
||||
|
||||
defer func() { require.NoError(t, r.Close()) }()
|
||||
|
||||
b, err := io.ReadAll(r)
|
||||
require.NoError(t, err)
|
||||
b, fErr := io.ReadAll(r)
|
||||
require.NoError(t, fErr)
|
||||
|
||||
require.Equal(t, wantBytes, b)
|
||||
return nil
|
||||
@ -180,8 +181,7 @@ func TestTName(t *testing.T) {
|
||||
got := tutil.Name(tc.a...)
|
||||
require.Equal(t, tc.want, got)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Keep the q lib around
|
||||
// Keep the q lib around.
|
||||
var _ = q.Q
|
||||
|
Loading…
Reference in New Issue
Block a user