From 9ce69b41195451b9ebbf2b0fbea732c8e7de3fcc Mon Sep 17 00:00:00 2001 From: kcmvp Date: Mon, 17 Jun 2024 17:20:48 +0800 Subject: [PATCH] #33: code refactor for type finding --- function.go | 8 ++++---- internal/artifact_test.go | 2 +- type.go | 40 ++++++++++++++++++++------------------- type_test.go | 34 +++++++++++++++++---------------- 4 files changed, 44 insertions(+), 40 deletions(-) diff --git a/function.go b/function.go index d21423f..7ec43ba 100644 --- a/function.go +++ b/function.go @@ -2,17 +2,17 @@ package archunit import ( + "fmt" "github.com/kcmvp/archunit/internal" "github.com/samber/lo" - "log" ) type Functions []internal.Function -func FunctionsOfType(fTypName string) Functions { +func FunctionsOfType(fTypName string) (Functions, error) { typ, ok := internal.Arch().Type(fTypName) if !ok || !typ.FuncType() { - log.Fatalf("can not find function type %s", fTypName) + return Functions{}, fmt.Errorf("can not find function type %s", fTypName) } lo.ForEach(lo.Filter(internal.Arch().Packages(), func(pkg *internal.Package, _ int) bool { return lo.Contains(pkg.Imports(), typ.Package()) @@ -29,7 +29,7 @@ func FunctionsOfType(fTypName string) Functions { // } //} - return Functions{} + return Functions{}, nil } func (functions Functions) Exclude(names ...string) Functions { diff --git a/internal/artifact_test.go b/internal/artifact_test.go index b6eeada..e3c79a9 100644 --- a/internal/artifact_test.go +++ b/internal/artifact_test.go @@ -145,12 +145,12 @@ func TestPackage_Functions(t *testing.T) { "github.com/kcmvp/archunit/internal", "github.com/samber/lo", "go/types", - "log", "path/filepath", "regexp", "strings", "github.com/samber/lo/parallel", "sync", + "errors", }, exists: true, }, diff --git a/type.go b/type.go index f8d1fb3..5ce407a 100644 --- a/type.go +++ b/type.go @@ -2,12 +2,12 @@ package archunit import ( + "errors" "fmt" "github.com/kcmvp/archunit/internal" "github.com/samber/lo" lop "github.com/samber/lo/parallel" "go/types" - "log" "strings" "sync" ) @@ -30,10 +30,10 @@ func TypesWith(typeNames ...string) Types { } // TypesEmbeddedWith returns all the types that embed the specified type -func TypesEmbeddedWith(embeddedType string) Types { +func TypesEmbeddedWith(embeddedType string) (Types, error) { eType, ok := internal.Arch().Type(embeddedType) if !ok { - log.Fatalf("can not find interface %s", embeddedType) + return Types{}, fmt.Errorf("can not find interface %s", embeddedType) } var typMap sync.Map lo.ForEach(internal.Arch().Packages(), func(pkg *internal.Package, index int) { @@ -55,14 +55,14 @@ func TypesEmbeddedWith(embeddedType string) Types { typs = append(typs, value.(internal.Type)) return true }) - return typs + return typs, nil } // TypesImplement return all the types implement the interface -func TypesImplement(interName string) Types { +func TypesImplement(interName string) (Types, error) { interType, ok := internal.Arch().Type(interName) if !ok || !interType.Interface() { - log.Fatalf("can not find interface %s", interName) + return Types{}, errors.New(lo.If(!ok, fmt.Sprintf("can not find interface %s", interName)).Else("")) } var typMap sync.Map lo.ForEach(internal.Arch().Packages(), func(pkg *internal.Package, index int) { @@ -80,7 +80,7 @@ func TypesImplement(interName string) Types { typs = append(typs, value.(internal.Type)) return true }) - return typs + return typs, nil } // Skip filter out the specified types @@ -91,30 +91,32 @@ func (types Types) Skip(typNames ...string) Types { } // EmbeddedWith return types that embed the specified types -func (types Types) EmbeddedWith(embedTyps ...string) Types { - embedded := lo.Map(embedTyps, func(typName string, _ int) internal.Type { +func (types Types) EmbeddedWith(embedTyps ...string) (Types, error) { + var embedded []internal.Type + for _, typName := range embedTyps { t, ok := internal.Arch().Type(typName) if !ok { - log.Fatalf("can not find type %s", typName) + return Types{}, fmt.Errorf("can not find type %s", typName) } - return t - }) + embedded = append(embedded, t) + } return lo.Filter(types, func(typ internal.Type, _ int) bool { return lo.Contains(embedded, typ) - }) + }), nil } -func (types Types) Implement(interTyps ...string) Types { - inters := lo.Map(interTyps, func(typName string, _ int) internal.Type { +func (types Types) Implement(interTyps ...string) (Types, error) { + var inters []internal.Type + for _, typName := range interTyps { t, ok := internal.Arch().Type(typName) if !ok { - log.Fatalf("can not find type %s", typName) + return Types{}, fmt.Errorf("can not find type %s", typName) } - return t - }) + inters = append(inters, t) + } return lo.Filter(types, func(typ internal.Type, _ int) bool { return lo.Contains(inters, typ) - }) + }), nil } // InPackages return types in the specified packages diff --git a/type_test.go b/type_test.go index 0468fc9..c181161 100644 --- a/type_test.go +++ b/type_test.go @@ -55,6 +55,7 @@ func TestTypeImplement(t *testing.T) { tests := []struct { interType string implementation []string + hasError bool }{ { interType: "internal/sample/service.NameService", @@ -69,19 +70,18 @@ func TestTypeImplement(t *testing.T) { "github.com/kcmvp/archunit/internal/sample/controller.AppContext", }, }, - //{ - // interType: "github.com/gin-gonic/gin.IRouter", - // implementation: []string{ - // "github.com/kcmvp/archunit/internal/sample/controller.MyRouterGroup", - // }, - //}, + { + interType: "github.com/gin-gonic/gin.IRouter", + hasError: true, + }, } for _, test := range tests { t.Run(test.interType, func(t *testing.T) { - types := lo.Map(TypesImplement(test.interType), func(item internal.Type, _ int) string { + types, err := TypesImplement(test.interType) + assert.Equal(t, test.hasError, err != nil) + assert.ElementsMatch(t, test.implementation, lo.Map(types, func(item internal.Type, _ int) string { return item.Name() - }) - assert.ElementsMatch(t, test.implementation, types) + })) }) } } @@ -90,6 +90,7 @@ func TestTypesEmbeddedWith(t *testing.T) { tests := []struct { interType string implementation []string + hasError bool }{ { interType: "context.Context", @@ -97,17 +98,18 @@ func TestTypesEmbeddedWith(t *testing.T) { "github.com/kcmvp/archunit/internal/sample/controller.AppContext", }, }, - //{ - // interType: "github.com/gin-gonic/gin.IRouter", - // implementation: []string{}, - //}, + { + interType: "github.com/gin-gonic/gin.IRouter", + hasError: true, + }, } for _, test := range tests { t.Run(test.interType, func(t *testing.T) { - types := lo.Map(TypesEmbeddedWith(test.interType), func(item internal.Type, _ int) string { + types, err := TypesEmbeddedWith(test.interType) + assert.Equal(t, test.hasError, err != nil) + assert.ElementsMatch(t, test.implementation, lo.Map(types, func(item internal.Type, _ int) string { return item.Name() - }) - assert.ElementsMatch(t, test.implementation, types) + })) }) } }