Skip to content

Commit

Permalink
Merge pull request #18 from kcmvp/test
Browse files Browse the repository at this point in the history
#11: add test for lay reference
  • Loading branch information
kcmvp authored May 11, 2024
2 parents 4133514 + 37e54df commit d920770
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 34 deletions.
6 changes: 6 additions & 0 deletions internal/sample/repository/user_repository.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
package repository

import "github.com/kcmvp/archunit/internal/sample/model"

const (
Mast = "1"
Slave = "2"
)

type UserRepository struct {
}

func (u UserRepository) FindUser() model.User {
panic("implement me")
}
56 changes: 29 additions & 27 deletions layer.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ import (

type NamePattern func(name, arg string) bool

func BeLowerCase(name, _ string) bool {
func LowerCase(name, _ string) bool {
return strings.ToLower(name) == name
}
func BeUpperCase(name, _ string) bool {
func UpperCase(name, _ string) bool {
return strings.ToUpper(name) == name
}
func HavePrefix(name, prefix string) bool {
Expand All @@ -36,20 +36,24 @@ func PackageNameShouldBeSameAsFolderName() error {
return nil
}

func PackageNameShould(pattern NamePattern, args ...string) error {
func PackageNameShouldBe(pattern NamePattern, args ...string) error {
if pkg, ok := lo.Find(internal.Arch().AllPackages(), func(item lo.Tuple2[string, string]) bool {
return !pattern(item.A, lo.If(args != nil, args[0]).Else(""))
return !pattern(item.A, lo.If(args == nil, "").ElseF(func() string {
return args[0]
}))
}); ok {
return fmt.Errorf("package %s's name is %s", pkg.A, pkg.B)
}
return nil
}

func SourceNameShould(pattern NamePattern, args ...string) error {
func SourceNameShouldBe(pattern NamePattern, args ...string) error {
if file, ok := lo.Find(internal.Arch().AllSources(), func(file string) bool {
return !pattern(filepath.Base(file), lo.If(args != nil, args[0]).Else(""))
return !pattern(filepath.Base(file), lo.If(args == nil, "").ElseF(func() string {
return args[0]
}))
}); ok {
return fmt.Errorf("file %s's name valid break the rule", file)
return fmt.Errorf("file %s's name breaks the rule", file)
}
return nil
}
Expand Down Expand Up @@ -105,7 +109,7 @@ func TypeImplement(interName string) []Type {

type Layer lo.Tuple2[string, []*internal.Package]

func Packages(layerName string, paths ...string) Layer {
func Packages(layerName string, paths []string) Layer {
patterns := lo.Map(paths, func(path string, _ int) *regexp.Regexp {
reg, err := internal.PkgPattern(path)
if err != nil {
Expand Down Expand Up @@ -159,13 +163,13 @@ func (layer Layer) Sub(name string, paths ...string) Layer {
})}
}

func (layer Layer) packages() []string {
func (layer Layer) Packages() []string {
return lo.Map(layer.B, func(item *internal.Package, _ int) string {
return item.ID()
})
}

func (layer Layer) imports() []string {
func (layer Layer) Imports() []string {
var imports []string
for _, pkg := range layer.B {
imports = append(imports, pkg.Imports()...)
Expand All @@ -174,35 +178,33 @@ func (layer Layer) imports() []string {
}

func (layer Layer) ShouldNotReferLayers(layers ...Layer) error {
path, ok := lo.Find(layer.imports(), func(ref string) bool {
return lo.Contains(layer.packages(), ref)
})
if ok {
fmt.Errorf("%s refers %s", layer.A, path)
var packages []string
for _, l := range layers {
packages = append(packages, l.Packages()...)
}
return nil
path, ok := lo.Find(layer.Imports(), func(ref string) bool {
return lo.Contains(packages, ref)
})
return lo.If(ok, fmt.Errorf("%s refers %s", layer.A, path)).Else(nil)
}

func (layer Layer) ShouldNotReferPackages(paths ...string) error {
return layer.ShouldNotReferLayers(Packages("_", paths...))
return layer.ShouldNotReferLayers(Packages("_", paths))
}

func (layer Layer) ShouldOnlyReferLayers(layers ...Layer) error {
var pkgs []string
for _, l := range layers {
pkgs = append(pkgs, l.packages()...)
pkgs = append(pkgs, l.Packages()...)
}
ref, ok := lo.Find(layer.imports(), func(ref string) bool {
return lo.Contains(pkgs, ref)
ref, ok := lo.Find(layer.Imports(), func(ref string) bool {
return !lo.Contains(pkgs, ref)
})
if ok {
return fmt.Errorf("%s refers %s", layer.A, ref)
}
return nil
return lo.If(ok, fmt.Errorf("%s refers %s", layer.A, ref)).Else(nil)
}

func (layer Layer) ShouldOnlyReferPackages(paths ...string) error {
return layer.ShouldOnlyReferLayers(Packages("tempLayer", paths...))
return layer.ShouldOnlyReferLayers(Packages("tempLayer", paths))
}

func (layer Layer) ShouldBeOnlyReferredByLayers(layers ...Layer) error {
Expand All @@ -217,7 +219,7 @@ func (layer Layer) ShouldBeOnlyReferredByLayers(layers ...Layer) error {
})
if p, ok := lo.Find(others, func(other *internal.Package) bool {
return lo.SomeBy(other.Imports(), func(ref string) bool {
return lo.Contains(layer.imports(), ref)
return lo.Contains(layer.Imports(), ref)
})
}); ok {
return fmt.Errorf("package %s refer layer %s", p.ID(), layer.A)
Expand All @@ -226,7 +228,7 @@ func (layer Layer) ShouldBeOnlyReferredByLayers(layers ...Layer) error {
}

func (layer Layer) ShouldBeOnlyReferredByPackages(paths ...string) error {
layer1 := Packages("pkgLayer", paths...)
layer1 := Packages("pkgLayer", paths)
return layer.ShouldBeOnlyReferredByLayers(layer1)
}

Expand Down
64 changes: 57 additions & 7 deletions layer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ func TestPackages(t *testing.T) {
size1: 0,
},
{
name: "sample and sub packages",
name: "sample and sub Packages",
paths: []string{".../internal/sample/..."},
except: []string{".../ext"},
size1: 12,
Expand All @@ -40,11 +40,11 @@ func TestPackages(t *testing.T) {
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
layer := Packages(test.name, test.paths...)
assert.Equal(t, test.size1, len(layer.packages()))
layer := Packages(test.name, test.paths)
assert.Equal(t, test.size1, len(layer.Packages()))
if len(test.except) > 0 {
layer = layer.Exclude(test.except...)
assert.Equal(t, test.size2, len(layer.packages()))
assert.Equal(t, test.size2, len(layer.Packages()))
}
})
}
Expand Down Expand Up @@ -75,10 +75,10 @@ func TestLayer_Sub(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
layer := Packages(tt.name, tt.paths...)
assert.Equal(t, tt.size1, len(layer.packages()))
layer := Packages(tt.name, tt.paths)
assert.Equal(t, tt.size1, len(layer.Packages()))
layer = layer.Sub(tt.name, tt.sub...)
assert.Equal(t, tt.size2, len(layer.packages()))
assert.Equal(t, tt.size2, len(layer.Packages()))
})
}
}
Expand All @@ -101,3 +101,53 @@ func TestTypeImplement(t *testing.T) {
"github.com/kcmvp/archunit/internal/sample/service.FullNameImpl",
}, types))
}

func TestPackageNameShouldBeSameAsFolderName(t *testing.T) {
err := PackageNameShouldBeSameAsFolderName()
assert.Error(t, err)
assert.True(t, strings.Contains(err.Error(), "github.com/kcmvp/archunit/internal/sample/views's name is view"))
}

func TestPackageNameShould(t *testing.T) {
err := PackageNameShouldBe(LowerCase)
assert.NoError(t, err)
err = PackageNameShouldBe(UpperCase)
assert.Error(t, err)
}

func TestSourceNameShould(t *testing.T) {
err := SourceNameShouldBe(LowerCase)
assert.Error(t, err)
assert.True(t, strings.Contains(err.Error(), "internal/sample/views/UserView.go's name breaks the rule"))
}

func TestConstantsShouldBeDefinedInOneFileByPackage(t *testing.T) {
err := ConstantsShouldBeDefinedInOneFileByPackage()
assert.Error(t, err)
assert.True(t, strings.Contains(err.Error(), "package github.com/kcmvp/archunit/internal/sample/repository constants are definied in files "))
}

func TestLayPackages(t *testing.T) {
layer := Packages("controllerLayer", []string{"sample/controller", "sample/controller/..."})
assert.ElementsMatch(t, []string{"github.com/kcmvp/archunit/internal/sample/controller",
"github.com/kcmvp/archunit/internal/sample/controller/module1"}, layer.Packages())
assert.ElementsMatch(t, []string{"github.com/kcmvp/archunit/internal/sample/service",
"github.com/kcmvp/archunit/internal/sample/views",
"github.com/kcmvp/archunit/internal/sample/repository",
"github.com/kcmvp/archunit/internal/sample/service/ext/v1"}, layer.Imports())
}

func TestLayer_Refer(t *testing.T) {
controller := Packages("controller", []string{"sample/controller", "sample/controller/..."})
model := Packages("model", []string{"sample/model"})
service := Packages("service", []string{"sample/service", "sample/service/..."})
repository := Packages("repository", []string{"sample/repository", "sample/repository/..."})
assert.NoError(t, controller.ShouldNotReferLayers(model))
assert.NoError(t, controller.ShouldNotReferPackages("sample/model"))
assert.Errorf(t, controller.ShouldNotReferLayers(repository), "controller should not refer repository")
assert.Error(t, controller.ShouldOnlyReferLayers(service))
assert.NoError(t, repository.ShouldOnlyReferLayers(model), "repository should not refer model")
assert.NoError(t, repository.ShouldOnlyReferPackages("sample/model"), "repository should not refer model")
assert.NoError(t, model.ShouldBeOnlyReferredByLayers(repository), "model should be only referred repository")
assert.Error(t, repository.ShouldBeOnlyReferredByLayers(service), "repository is referenced by controller")
}

0 comments on commit d920770

Please sign in to comment.