Skip to content

Commit

Permalink
fix: [#5] Add unit testing
Browse files Browse the repository at this point in the history
  • Loading branch information
sbp-bvanb committed Nov 1, 2024
1 parent 867ac59 commit 1e350ba
Show file tree
Hide file tree
Showing 10 changed files with 387 additions and 13 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/golang.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
- uses: actions/[email protected]
- uses: schubergphilis/[email protected]
with:
code-coverage-expected: 62.3
code-coverage-expected: 84.9
gci: "false"
golang-unit-tests-exclusions: |-
\(cmd\/prolayout\)
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
.task
.vscode
coverage.html
functioncoverage.out
profile.cov
reports
7 changes: 5 additions & 2 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ linters:
- nilnil
- nlreturn
- paralleltest
- testpackage
- varnamelen
- wsl

Expand All @@ -147,14 +148,16 @@ issues:
- path: _test\.go
linters:
- funlen

- linters:
- staticcheck
text: "SA9003:"

- linters:
- lll
text: "^//go:generate "
- linters:
- revive
path: internal/analyzer/analyzer.go
text: "cyclomatic: function \\(\\*runner\\).assessDir has cyclomatic complexity 8 \\(\\> max enabled 7\\)"

exclude-use-default: false

Expand Down
2 changes: 2 additions & 0 deletions .prolayout.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@
module: "github.com/wimspaargaren/prolayout"
root:
- name: "bar"
- name: "internal"
- name: "tests"
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ fashion.

## Example configuration file

```YAML
```yml
module: "github.com/wimspaargaren/prolayout"
root:
- name: "cmd"
Expand All @@ -35,3 +35,5 @@ root:
files:
- name: ".*_test.go"
```
and run `prolayout ./...`
9 changes: 5 additions & 4 deletions internal/analyzer/analyzer.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,7 @@ func (r *runner) assessDir(pass *analysis.Pass) (*model.Dir, error) {
dir := &model.Dir{}

for _, folder := range packageSplittedPerFolder {
if len(dirs) == 0 {
return nil, nil
}
if strings.HasSuffix(folder, ".test") {
if len(dirs) == 0 || strings.HasSuffix(folder, ".test") {
return nil, nil
}

Expand All @@ -70,12 +67,16 @@ func (r *runner) assessDir(pass *analysis.Pass) (*model.Dir, error) {
return nil, err
}
if !ok {
if len(pass.Files) == 0 || packagePathWithoutModule == "" {
continue
}
pass.ReportRangef(pass.Files[0], "package not allowed: %s, %s not found in allowed names: [%s]", packagePathWithoutModule, folder, strings.Join(dirsNames(dirs), ","))
break
}
dir = res
dirs = res.Dirs
}

return dir, nil
}

Expand Down
253 changes: 253 additions & 0 deletions internal/analyzer/analyzer_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,253 @@
package analyzer

import (
"go/types"
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"golang.org/x/tools/go/analysis"

"github.com/wimspaargaren/prolayout/internal/errors"
"github.com/wimspaargaren/prolayout/internal/model"
)

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
}
require.NoError(t, err)
assert.Equal(t, tc.expected, dir)
})
}
}

func TestDirsNames(t *testing.T) {
testCases := []struct {
name string
dirs []*model.Dir
expected []string
}{
{
name: "multiple directories",
dirs: []*model.Dir{
{Name: "dir1"},
{Name: "dir2"},
{Name: "dir3"},
},
expected: []string{"dir1", "dir2", "dir3"},
},
{
name: "single directory",
dirs: []*model.Dir{
{Name: "dir1"},
},
expected: []string{"dir1"},
},
{
name: "no directories",
dirs: []*model.Dir{},
expected: []string{},
},
{
name: "directories with empty names",
dirs: []*model.Dir{
{Name: ""},
{Name: ""},
},
expected: []string{"", ""},
},
{
name: "nil directory slice",
dirs: nil,
expected: []string{},
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
result := dirsNames(tc.dirs)
assert.Equal(t, tc.expected, result)
})
}
}

func TestMatchFiles(t *testing.T) {
r := &runner{}

testCases := []struct {
name string
files []*model.File
input string
expectedOk bool
expectedErr error
}{
{
name: "valid match",
files: []*model.File{
{Name: "^file1.go$"},
{Name: "^file2.go$"},
},
input: "file2",
expectedOk: true,
expectedErr: nil,
},
{
name: "no match",
files: []*model.File{
{Name: "^file1$"},
{Name: "^file2$"},
},
input: "file3",
expectedOk: false,
expectedErr: nil,
},
{
name: "invalid regular expression",
files: []*model.File{
{Name: "file1["}, // invalid regex
},
input: "file1",
expectedOk: false,
expectedErr: errors.ErrInvalidFileNameRegex{FileName: "file1["},
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
ok, err := r.matchFiles(tc.files, tc.input)

if tc.expectedErr != nil {
require.Error(t, err)
assert.Equal(t, tc.expectedErr, err)
return
}
require.NoError(t, err)
assert.Equal(t, tc.expectedOk, ok)
})
}
}

func TestMatchDir(t *testing.T) {
testCases := []struct {
name string
dirs []*model.Dir
input string
expectedDir *model.Dir
expectedOk bool
expectedErr error
}{
{
name: "valid match",
dirs: []*model.Dir{
{Name: "^dir1$"},
{Name: "^dir2$"},
},
input: "dir1",
expectedDir: &model.Dir{Name: "^dir1$"},
expectedOk: true,
expectedErr: nil,
},
{
name: "no match",
dirs: []*model.Dir{
{Name: "^dir1$"},
{Name: "^dir2$"},
},
input: "dir3",
expectedDir: nil,
expectedOk: false,
expectedErr: nil,
},
{
name: "invalid regular expression",
dirs: []*model.Dir{
{Name: "dir1["}, // invalid regex
},
input: "dir1",
expectedDir: nil,
expectedOk: false,
expectedErr: errors.ErrInvalidDirNameRegex{DirName: "dir1["},
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
dir, ok, err := matchDir(tc.dirs, tc.input)

if tc.expectedErr != nil {
require.Error(t, err)
assert.Equal(t, tc.expectedErr, err)
return
}
require.NoError(t, err)

assert.Equal(t, tc.expectedOk, ok)
assert.Equal(t, tc.expectedDir, dir)
})
}
}

func TestSplitPath(t *testing.T) {
testCases := []struct {
path string
expected []string
}{
{
path: "dir1/dir2/file.txt",
expected: []string{"dir1", "dir2", "file.txt"},
},
{
path: "singlefile",
expected: []string{"singlefile"},
},
{
path: "dir1/dir2/dir3/",
expected: []string{"dir1", "dir2", "dir3", ""},
},
{
path: "/leading/slash",
expected: []string{"", "leading", "slash"},
},
{
path: "",
expected: []string{""},
},
}

for _, tc := range testCases {
t.Run(tc.path, func(t *testing.T) {
result := splitPath(tc.path)
assert.Equal(t, tc.expected, result)
})
}
}
Loading

0 comments on commit 1e350ba

Please sign in to comment.