From 77791a51d4fae484d14d5235c27e53d9df7be4a9 Mon Sep 17 00:00:00 2001 From: sbp-bvanb Date: Fri, 1 Nov 2024 08:56:29 +0100 Subject: [PATCH] fix: [#5] Add unit testing --- .gitignore | 3 ++ .golangci.yml | 1 + .prolayout.yml | 2 ++ README.md | 4 ++- go.mod | 2 ++ go.sum | 9 ++++++ internal/analyzer/analyzer.go | 10 ++++++ internal/analyzer/analyzer_test.go | 49 ++++++++++++++++++++++++++++++ main.go | 24 ++++++++++++--- main_test.go | 24 +++++++++++++++ 10 files changed, 122 insertions(+), 6 deletions(-) create mode 100644 internal/analyzer/analyzer_test.go create mode 100644 main_test.go diff --git a/.gitignore b/.gitignore index b5b4faa..f4a1928 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ .task .vscode +coverage.html +functioncoverage.out +profile.cov reports diff --git a/.golangci.yml b/.golangci.yml index b0dfc56..b9a902b 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -130,6 +130,7 @@ linters: - nilnil - nlreturn - paralleltest + - testpackage - varnamelen - wsl diff --git a/.prolayout.yml b/.prolayout.yml index 491db75..08530dc 100644 --- a/.prolayout.yml +++ b/.prolayout.yml @@ -2,3 +2,5 @@ module: "github.com/wimspaargaren/prolayout" root: - name: "bar" + - name: "internal" + - name: "tests" diff --git a/README.md b/README.md index abb3a03..9469260 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ fashion. ## Example configuration file -```YAML +```yml module: "github.com/wimspaargaren/prolayout" root: - name: "cmd" @@ -35,3 +35,5 @@ root: files: - name: ".*_test.go" ``` + +and run `prolayout ./...` diff --git a/go.mod b/go.mod index 7a041a8..4a19e9f 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module github.com/wimspaargaren/prolayout go 1.23.0 require ( + github.com/sirupsen/logrus v1.9.3 github.com/stretchr/testify v1.9.0 golang.org/x/tools v0.20.0 gopkg.in/yaml.v3 v3.0.1 @@ -13,4 +14,5 @@ require ( github.com/pmezard/go-difflib v1.0.0 // indirect golang.org/x/mod v0.17.0 // indirect golang.org/x/sync v0.7.0 // indirect + golang.org/x/sys v0.19.0 // indirect ) diff --git a/go.sum b/go.sum index 9b02d14..36765d2 100644 --- a/go.sum +++ b/go.sum @@ -1,16 +1,25 @@ +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= +golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/tools v0.20.0 h1:hz/CVckiOxybQvFw6h7b/q80NTr9IUQb4s1IIzW7KNY= golang.org/x/tools v0.20.0/go.mod h1:WvitBU7JJf6A4jOdg4S1tviW9bhUxkgeCui/0JHctQg= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/internal/analyzer/analyzer.go b/internal/analyzer/analyzer.go index 38be6a0..762a2ef 100644 --- a/internal/analyzer/analyzer.go +++ b/internal/analyzer/analyzer.go @@ -69,6 +69,15 @@ func (r *runner) assessDir(pass *analysis.Pass) (*model.Dir, error) { if err != nil { return nil, err } + + if len(pass.Files) == 0 { + continue + } + + if packagePathWithoutModule == "" { + continue + } + if !ok { pass.ReportRangef(pass.Files[0], "package not allowed: %s, %s not found in allowed names: [%s]", packagePathWithoutModule, folder, strings.Join(dirsNames(dirs), ",")) break @@ -76,6 +85,7 @@ func (r *runner) assessDir(pass *analysis.Pass) (*model.Dir, error) { dir = res dirs = res.Dirs } + return dir, nil } diff --git a/internal/analyzer/analyzer_test.go b/internal/analyzer/analyzer_test.go new file mode 100644 index 0000000..8d106a0 --- /dev/null +++ b/internal/analyzer/analyzer_test.go @@ -0,0 +1,49 @@ +package analyzer + +import ( + "go/types" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/wimspaargaren/prolayout/internal/model" + "golang.org/x/tools/go/analysis" +) + +func TestAssessDir(t *testing.T) { + testCases := []struct { + name string + pass *analysis.Pass + expected *model.Dir + hasError bool + }{ + { + name: "if folder contains a '.test' suffix, then skip assessDir and return nil twice", + pass: &analysis.Pass{ + Pkg: types.NewPackage("github.com/wimspaargaren/prolayout/tests.test", "main"), + }, + expected: nil, + hasError: false, + }, + { + name: "if folder contains a '.something' suffix, then loop through and return 'dir *model.Dir' at the end", + pass: &analysis.Pass{ + Pkg: types.NewPackage("github.com/wimspaargaren/prolayout/tests.something", "main"), + }, + expected: &model.Dir{Name: "", Files: []*model.File(nil), Dirs: []*model.Dir(nil)}, + hasError: false, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + r := &runner{Root: model.Root{Root: []*model.Dir{{Name: "internal"}}}} + dir, err := r.assessDir(tc.pass) + if tc.hasError { + assert.Error(t, err) + return + } + assert.NoError(t, err) + assert.Equal(t, tc.expected, dir) + }) + } +} diff --git a/main.go b/main.go index 5011e0f..f07663d 100644 --- a/main.go +++ b/main.go @@ -2,8 +2,10 @@ package main import ( + "fmt" "log" "os" + "path/filepath" "golang.org/x/tools/go/analysis/singlechecker" "gopkg.in/yaml.v3" @@ -12,15 +14,27 @@ import ( "github.com/wimspaargaren/prolayout/internal/model" ) -func main() { - data, err := os.ReadFile(".prolayout.yml") +const proLayoutFile = ".prolayout.yml" + +func readAndUnmarshalProLayoutYML(proLayoutFile string) (*model.Root, error) { + data, err := os.ReadFile(filepath.Clean(proLayoutFile)) if err != nil { - log.Fatalf("error: %v", err) + return nil, fmt.Errorf("'%w'", err) } t := model.Root{} err = yaml.Unmarshal(data, &t) if err != nil { - log.Fatalf("error: %v", err) + return nil, fmt.Errorf("'%w'", err) } - singlechecker.Main(analyzer.New(t)) + + return &t, nil +} + +func main() { + unmarshalledProLayoutYML, err := readAndUnmarshalProLayoutYML(proLayoutFile) + if err != nil { + log.Fatalf("failed to unmarshal '%s': '%v'", proLayoutFile, err) + } + + singlechecker.Main(analyzer.New(*unmarshalledProLayoutYML)) } diff --git a/main_test.go b/main_test.go new file mode 100644 index 0000000..e467330 --- /dev/null +++ b/main_test.go @@ -0,0 +1,24 @@ +package main + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/wimspaargaren/prolayout/internal/model" +) + +func TestReadAndUnmarshalProLayoutYML(t *testing.T) { + exp := model.Root{ + Module: "github.com/wimspaargaren/prolayout", + Root: []*model.Dir{{Name: "bar"}, {Name: "internal"}, {Name: "tests"}}, + } + act, err := readAndUnmarshalProLayoutYML(proLayoutFile) + require.NoError(t, err) + assert.Equal(t, exp, *act) + + act, err = readAndUnmarshalProLayoutYML(proLayoutFile + "-does-not-exist") + require.Empty(t, act) + assert.EqualError(t, err, "'open .prolayout.yml-does-not-exist: no such file or directory'") +}