Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

No init() for checkers registry #2

Merged
merged 1 commit into from
Sep 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ linters:
- forbidigo
- gci
- gocheckcompilerdirectives
- gochecknoinits
- goconst
- gocritic
- godot
Expand Down
53 changes: 13 additions & 40 deletions internal/checkers/checkers_registry.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package checkers

import (
"fmt"
"sort"
)

Expand All @@ -23,19 +22,11 @@ var registry = checkersRegistry{
{factory: asCheckerFactory(NewSuiteTHelper), enabledByDefault: false},
}

func init() {
if err := registry.init(); err != nil {
panic(err)
}
}

type checkersRegistry []checkerMeta

type checkerMeta struct {
factory checkerFactory
enabledByDefault bool
priority int
name string
}

type checkerFactory func() Checker
Expand All @@ -46,38 +37,20 @@ func asCheckerFactory[T Checker](fn func() T) checkerFactory {
}
}

func (r checkersRegistry) init() error {
for i := range r {
checker := &r[i]

name := checker.factory().Name()
if name == "" {
return fmt.Errorf("checker with empty name: %T", checker)
}
if _, ok := r.get(name); ok {
return fmt.Errorf("not uniq checker name: %v", name)
}

checker.name = name
checker.priority = i
}
return nil
}

func (r checkersRegistry) get(name string) (checkerMeta, bool) {
for _, meta := range r {
if meta.name == name {
return meta, true
func (r checkersRegistry) get(name string) (m checkerMeta, priority int, found bool) {
for i, meta := range r {
if meta.factory().Name() == name {
return meta, i, true
}
}
return checkerMeta{}, false
return checkerMeta{}, 0, false
}

// All returns all checkers names sorted by checker's priority.
func All() []string {
result := make([]string, 0, len(registry))
for _, meta := range registry {
result = append(result, meta.name)
result = append(result, meta.factory().Name())
}
return result
}
Expand All @@ -87,15 +60,15 @@ func EnabledByDefault() []string {
result := make([]string, 0, len(registry))
for _, meta := range registry {
if meta.enabledByDefault {
result = append(result, meta.name)
result = append(result, meta.factory().Name())
}
}
return result
}

// Get returns new checker instance by checker's name.
func Get(name string) (Checker, bool) {
meta, ok := registry.get(name)
meta, _, ok := registry.get(name)
if ok {
return meta.factory(), true
}
Expand All @@ -104,15 +77,15 @@ func Get(name string) (Checker, bool) {

// IsKnown checks if there is a checker with that name.
func IsKnown(name string) bool {
_, ok := registry.get(name)
_, _, ok := registry.get(name)
return ok
}

// IsEnabledByDefault returns true if a checker is enabled by default.
// Returns false if there is no such checker in the registry.
// For pre-validation use Get or IsKnown.
func IsEnabledByDefault(name string) bool {
meta, ok := registry.get(name)
meta, _, ok := registry.get(name)
return ok && meta.enabledByDefault
}

Expand All @@ -121,8 +94,8 @@ func IsEnabledByDefault(name string) bool {
func SortByPriority(checkers []string) {
sort.Slice(checkers, func(i, j int) bool {
lhs, rhs := checkers[i], checkers[j]
lhsMeta, _ := registry.get(lhs)
rhsMeta, _ := registry.get(rhs)
return lhsMeta.priority < rhsMeta.priority
_, lhsPriority, _ := registry.get(lhs)
_, rhsPriority, _ := registry.get(rhs)
return lhsPriority < rhsPriority
})
}
21 changes: 20 additions & 1 deletion internal/checkers/checkers_registry_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,29 @@ import (
"github.com/Antonboom/testifylint/internal/checkers"
)

func TestRegistry(t *testing.T) {
checkerList := checkers.All()
if len(checkerList) == 0 {
t.Fatal("no known checkers: empty list")
}

checkerSet := make(map[string]struct{}, len(checkerList))
for _, name := range checkerList {
if name == "" {
t.Fatal("empty checker name")
}

if _, ok := checkerSet[name]; ok {
t.Fatalf("not uniq checker name: %v", name)
}
checkerSet[name] = struct{}{}
}
}

func TestAll(t *testing.T) {
checkerList := checkers.All()
if len(checkerList) == 0 {
t.Fatalf("no known checkers: empty list")
t.Fatal("no known checkers: empty list")
}

// NOTE(a.telyshev): I don't use constants or checker's Name() method on purpose.
Expand Down
2 changes: 1 addition & 1 deletion internal/testgen/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ var checkerTestsGenerators = []CheckerTestsGenerator{
SuiteTHelperTestsGenerator{},
}

func init() {
func init() { //nolint:gochecknoinits // Internal test generation tool.
genForChecker := make(map[string]struct{}, len(checkerTestsGenerators))
for _, g := range checkerTestsGenerators {
name := g.Checker().Name()
Expand Down
Loading