From a941151610d067b0776084a22eaea0885935c5af Mon Sep 17 00:00:00 2001 From: Patrick DeVivo Date: Thu, 12 Aug 2021 10:02:17 -0400 Subject: [PATCH] add some test cases for `go_mod_to_json` and some better edge case handling --- extensions/internal/golang/go_mod_to_json.go | 20 ++++- .../internal/golang/go_mod_to_json_test.go | 86 +++++++++++++++++++ extensions/internal/golang/go_test.go | 30 +++++++ .../internal/golang/testdata/GoModMissingVals | 10 +++ extensions/internal/golang/testdata/GoModOK | 39 +++++++++ 5 files changed, 182 insertions(+), 3 deletions(-) create mode 100644 extensions/internal/golang/go_mod_to_json_test.go create mode 100644 extensions/internal/golang/go_test.go create mode 100644 extensions/internal/golang/testdata/GoModMissingVals create mode 100644 extensions/internal/golang/testdata/GoModOK diff --git a/extensions/internal/golang/go_mod_to_json.go b/extensions/internal/golang/go_mod_to_json.go index 354f356c..c5c9c70c 100644 --- a/extensions/internal/golang/go_mod_to_json.go +++ b/extensions/internal/golang/go_mod_to_json.go @@ -58,20 +58,34 @@ func goModVersionToVersion(v module.Version) Version { func (f *GoModToJSON) Args() int { return 1 } func (f *GoModToJSON) Deterministic() bool { return true } func (f *GoModToJSON) Apply(context *sqlite.Context, value ...sqlite.Value) { - parsed, err := modfile.Parse("go.mod", value[0].Blob(), nil) + input := value[0].Blob() + + if len(input) == 0 { + context.ResultNull() + return + } + + parsed, err := modfile.Parse("go.mod", input, nil) if err != nil { context.ResultError(err) return } + file := &GoModFile{ - Version: goModVersionToVersion(parsed.Module.Mod), - Go: parsed.Go.Version, Require: make([]*Require, len(parsed.Require)), Exclude: make([]*Exclude, len(parsed.Exclude)), Replace: make([]*Replace, len(parsed.Replace)), Retract: make([]*Retract, len(parsed.Retract)), } + if parsed.Module != nil { + file.Version = goModVersionToVersion(parsed.Module.Mod) + } + + if parsed.Go != nil { + file.Go = parsed.Go.Version + } + for i, r := range parsed.Require { file.Require[i] = &Require{ Mod: goModVersionToVersion(r.Mod), diff --git a/extensions/internal/golang/go_mod_to_json_test.go b/extensions/internal/golang/go_mod_to_json_test.go new file mode 100644 index 00000000..39d12a7c --- /dev/null +++ b/extensions/internal/golang/go_mod_to_json_test.go @@ -0,0 +1,86 @@ +package golang + +import ( + "encoding/json" + "io/ioutil" + "testing" + + "github.com/askgitdev/askgit/extensions/internal/tools" +) + +func TestGoModToJSONOK(t *testing.T) { + goMod, err := ioutil.ReadFile("testdata/GoModOK") + if err != nil { + t.Fatal(err) + } + + rows, err := FixtureDatabase.Query("SELECT go_mod_to_json(?)", goMod) + if err != nil { + t.Fatal(err) + } + + rowNum, contents, err := tools.RowContent(rows) + if err != nil { + t.Fatalf("err %d at row Number %d", err, rowNum) + } + + var parsed map[string]interface{} + err = json.Unmarshal([]byte(contents[0][0]), &parsed) + if err != nil { + t.Fatal(err) + } + + goVersion := parsed["go"].(string) + if goVersion != "1.13" { + t.Fatalf("expected go version 1.13, got %s", goVersion) + } + + req := parsed["require"].([]interface{}) + if len(req) != 33 { + t.Fatalf("expected 33 required modules, got %d", len(req)) + } +} + +func TestGoModToJSONEmpty(t *testing.T) { + rows, err := FixtureDatabase.Query("SELECT go_mod_to_json('')") + if err != nil { + t.Fatal(err) + } + + rowNum, contents, err := tools.RowContent(rows) + if err != nil { + t.Fatalf("err %d at row Number %d", err, rowNum) + } + + if contents[0][0] != "NULL" { + t.Fatalf("expected NULL, got %s", contents[0][0]) + } +} + +func TestGoModToJSONMissingVals(t *testing.T) { + goMod, err := ioutil.ReadFile("testdata/GoModMissingVals") + if err != nil { + t.Fatal(err) + } + + rows, err := FixtureDatabase.Query("SELECT go_mod_to_json(?)", goMod) + if err != nil { + t.Fatal(err) + } + + rowNum, contents, err := tools.RowContent(rows) + if err != nil { + t.Fatalf("err %d at row Number %d", err, rowNum) + } + + var parsed map[string]interface{} + err = json.Unmarshal([]byte(contents[0][0]), &parsed) + if err != nil { + t.Fatal(err) + } + + goVersion := parsed["go"].(string) + if goVersion != "" { + t.Fatalf("expected no go version, got %s", goVersion) + } +} diff --git a/extensions/internal/golang/go_test.go b/extensions/internal/golang/go_test.go new file mode 100644 index 00000000..345dd563 --- /dev/null +++ b/extensions/internal/golang/go_test.go @@ -0,0 +1,30 @@ +package golang + +import ( + "database/sql" + "log" + "os" + "testing" + + _ "github.com/askgitdev/askgit/pkg/sqlite" + "go.riyazali.net/sqlite" +) + +// FixtureDatabase represents the database connection to run the test against +var FixtureDatabase *sql.DB + +func init() { + // register sqlite extension when this package is loaded + sqlite.Register(func(ext *sqlite.ExtensionApi) (_ sqlite.ErrorCode, err error) { + return Register(ext, nil) + }) +} + +func TestMain(m *testing.M) { + var err error + if FixtureDatabase, err = sql.Open("sqlite3", "file:testing.db?mode=memory"); err != nil { + log.Fatalf("failed to open database connection: %v", err) + } + + os.Exit(m.Run()) +} diff --git a/extensions/internal/golang/testdata/GoModMissingVals b/extensions/internal/golang/testdata/GoModMissingVals new file mode 100644 index 00000000..06dcab33 --- /dev/null +++ b/extensions/internal/golang/testdata/GoModMissingVals @@ -0,0 +1,10 @@ +module github.com/askgitdev/askgit + +require ( + github.com/BurntSushi/toml v0.3.1 + github.com/DATA-DOG/go-sqlmock v1.5.0 + github.com/Microsoft/go-winio v0.5.0 // indirect + github.com/ProtonMail/go-crypto v0.0.0-20210707164159-52430bf6b52c // indirect + github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d // indirect + github.com/augmentable-dev/vtab v0.0.0-20210717200339-0c8dcfe2033b +) diff --git a/extensions/internal/golang/testdata/GoModOK b/extensions/internal/golang/testdata/GoModOK new file mode 100644 index 00000000..0b9fa16c --- /dev/null +++ b/extensions/internal/golang/testdata/GoModOK @@ -0,0 +1,39 @@ +module github.com/askgitdev/askgit + +go 1.13 + +require ( + github.com/BurntSushi/toml v0.3.1 + github.com/DATA-DOG/go-sqlmock v1.5.0 + github.com/Microsoft/go-winio v0.5.0 // indirect + github.com/ProtonMail/go-crypto v0.0.0-20210707164159-52430bf6b52c // indirect + github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d // indirect + github.com/augmentable-dev/vtab v0.0.0-20210717200339-0c8dcfe2033b + github.com/clbanning/mxj/v2 v2.5.5 + github.com/dnaeon/go-vcr/v2 v2.0.1 + github.com/ghodss/yaml v1.0.0 + github.com/go-enry/go-enry/v2 v2.7.1 + github.com/go-git/go-billy/v5 v5.3.1 + github.com/go-git/go-git/v5 v5.4.2 + github.com/go-openapi/errors v0.20.0 // indirect + github.com/go-openapi/strfmt v0.20.1 // indirect + github.com/jedib0t/go-pretty v4.3.0+incompatible + github.com/kevinburke/ssh_config v1.1.0 // indirect + github.com/libgit2/git2go/v31 v31.4.14 + github.com/mattn/go-runewidth v0.0.13 // indirect + github.com/mattn/go-sqlite3 v1.14.8 + github.com/pkg/errors v0.9.1 + github.com/sergi/go-diff v1.2.0 // indirect + github.com/shurcooL/githubv4 v0.0.0-20201206200315-234843c633fa + github.com/shurcooL/graphql v0.0.0-20200928012149-18c5c3165e3a // indirect + github.com/spf13/cobra v1.2.1 + go.mongodb.org/mongo-driver v1.6.0 // indirect + go.riyazali.net/sqlite v0.0.0-20210707161919-414349b4032a + golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 // indirect + golang.org/x/mod v0.4.2 + golang.org/x/net v0.0.0-20210716203947-853a461950ff // indirect + golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914 + golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c // indirect + golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b + golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac +)