Skip to content

Commit

Permalink
chore: rewrite rule builder locking mechanism
Browse files Browse the repository at this point in the history
  • Loading branch information
omissis committed Aug 12, 2022
1 parent 77e3ceb commit bc3381b
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 17 deletions.
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ This project gives developers the ability to describe and check the architecture
## TODO

- [ ] add docs to tell what options each expression support (even better: enforce that using type system)
- [ ] replace panics with better error handling
- [ ] review rule builder locking
- [ ] add support for setting violations severity levels

## Desired usecases

Expand Down
56 changes: 41 additions & 15 deletions internal/arch/file/rule.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
package file

import (
"errors"
"goarkitect/internal/arch/rule"
)

var (
ErrRuleBuilderLocked = errors.New(
"this rule builder has been already used: create a new one if you want to test a new ruleset",
)
)

func All() *RuleBuilder {
return NewRuleBuilder()
}
Expand Down Expand Up @@ -41,47 +48,68 @@ type RuleBuilder struct {
}

func (rb *RuleBuilder) That(t rule.That) rule.Builder {
rb.assertNotLocked()
if rb.locked {
rb.addLockError()
return rb
}

rb.thats = []rule.That{t}

return rb
}

func (rb *RuleBuilder) AndThat(t rule.That) rule.Builder {
rb.assertNotLocked()
if rb.locked {
rb.addLockError()
return rb
}

rb.thats = append(rb.thats, t)

return rb
}

func (rb *RuleBuilder) Except(s ...rule.Except) rule.Builder {
rb.assertNotLocked()
if rb.locked {
rb.addLockError()
return rb
}

rb.excepts = s

return rb
}

func (rb *RuleBuilder) Should(e rule.Should) rule.Builder {
rb.assertNotLocked()
if rb.locked {
rb.addLockError()
return rb
}

rb.shoulds = []rule.Should{e}

return rb
}

func (rb *RuleBuilder) AndShould(e rule.Should) rule.Builder {
rb.assertNotLocked()
if rb.locked {
rb.addLockError()
return rb
}

rb.shoulds = append(rb.shoulds, e)

return rb
}

func (rb *RuleBuilder) Because(b rule.Because) ([]rule.Violation, []error) {
rb.assertNotLocked()
if rb.locked {
rb.addLockError()

return nil, rb.GetErrors()
}

rb.lock()

rb.because = b

Expand Down Expand Up @@ -111,13 +139,15 @@ func (rb *RuleBuilder) Because(b rule.Because) ([]rule.Violation, []error) {
}
}

rb.lock()

return rb.violations, rb.errors
}

func (rb *RuleBuilder) AddError(err error) {
rb.assertNotLocked()
for _, err := range rb.errors {
if errors.Is(err, ErrRuleBuilderLocked) {
return
}
}

rb.errors = append(rb.errors, err)
}
Expand All @@ -131,15 +161,11 @@ func (rb *RuleBuilder) GetFiles() []string {
}

func (rb *RuleBuilder) SetFiles(files []string) {
rb.assertNotLocked()

rb.files = files
}

func (rb *RuleBuilder) assertNotLocked() {
if rb.locked {
panic("this rule builder has been already used: create a new one if you want to test a new ruleset")
}
func (rb *RuleBuilder) addLockError() {
rb.AddError(ErrRuleBuilderLocked)
}

func (rb *RuleBuilder) lock() {
Expand Down
17 changes: 17 additions & 0 deletions internal/arch/file/rule_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package file_test

import (
"goarkitect/internal/arch/file"
"testing"
)

func Test_It_Adds_ErrRuleBuilderLocked_Only_Once(t *testing.T) {
rb := file.NewRuleBuilder()

rb.AddError(file.ErrRuleBuilderLocked)
rb.AddError(file.ErrRuleBuilderLocked)

if errs := rb.GetErrors(); len(errs) != 1 {
t.Errorf("Expected 1 error, got %d", len(errs))
}
}

0 comments on commit bc3381b

Please sign in to comment.