Skip to content

Commit

Permalink
Merge pull request #35 from hovsep/v.0.1.0
Browse files Browse the repository at this point in the history
V.0.1.0
  • Loading branch information
hovsep authored Sep 16, 2024
2 parents 07f1f82 + 708183b commit 0dcb84f
Show file tree
Hide file tree
Showing 19 changed files with 918 additions and 909 deletions.
68 changes: 31 additions & 37 deletions component/activation_result.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,6 @@ type ActivationResult struct {
err error
}

// ActivationResults is a collection
type ActivationResults map[string]*ActivationResult

// ActivationResultCode denotes a specific info about how a component been activated or why not activated at all
type ActivationResultCode int

Expand Down Expand Up @@ -43,6 +40,36 @@ func NewActivationResult(componentName string) *ActivationResult {
}
}

// ComponentName getter
func (ar *ActivationResult) ComponentName() string {
return ar.componentName
}

// Activated getter
func (ar *ActivationResult) Activated() bool {
return ar.activated
}

// Error getter
func (ar *ActivationResult) Error() error {
return ar.err
}

// Code getter
func (ar *ActivationResult) Code() ActivationResultCode {
return ar.code
}

// HasError returns true when activation result has an error
func (ar *ActivationResult) HasError() bool {
return ar.code == ActivationCodeReturnedError && ar.Error() != nil
}

// HasPanic returns true when activation result is derived from panic
func (ar *ActivationResult) HasPanic() bool {
return ar.code == ActivationCodePanicked && ar.Error() != nil
}

// SetActivated setter
func (ar *ActivationResult) SetActivated(activated bool) *ActivationResult {
ar.activated = activated
Expand Down Expand Up @@ -83,43 +110,10 @@ func (c *Component) newActivationCodeWaitingForInput() *ActivationResult {

// newActivationCodeReturnedError builds a specific activation result
func (c *Component) newActivationCodeReturnedError(err error) *ActivationResult {
return NewActivationResult(c.Name()).
SetActivated(true).
WithActivationCode(ActivationCodeReturnedError).
WithError(fmt.Errorf("component returned an error: %w", err))
return NewActivationResult(c.Name()).SetActivated(true).WithActivationCode(ActivationCodeReturnedError).WithError(fmt.Errorf("component returned an error: %w", err))
}

// newActivationCodePanicked builds a specific activation result
func (c *Component) newActivationCodePanicked(err error) *ActivationResult {
return NewActivationResult(c.Name()).SetActivated(true).WithActivationCode(ActivationCodePanicked).WithError(err)
}

// ComponentName getter
func (ar *ActivationResult) ComponentName() string {
return ar.componentName
}

// Activated getter
func (ar *ActivationResult) Activated() bool {
return ar.activated
}

// Error getter
func (ar *ActivationResult) Error() error {
return ar.err
}

// Code getter
func (ar *ActivationResult) Code() ActivationResultCode {
return ar.code
}

// HasError returns true when activation result has an error
func (ar *ActivationResult) HasError() bool {
return ar.code == ActivationCodeReturnedError && ar.Error() != nil
}

// HasPanic returns true when activation result is derived from panic
func (ar *ActivationResult) HasPanic() bool {
return ar.code == ActivationCodePanicked && ar.Error() != nil
}
47 changes: 47 additions & 0 deletions component/activation_result_collection.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package component

// ActivationResultCollection is a collection
type ActivationResultCollection map[string]*ActivationResult

// NewActivationResultCollection creates empty collection
func NewActivationResultCollection() ActivationResultCollection {
return make(ActivationResultCollection)
}

// Add adds multiple activation results
func (collection ActivationResultCollection) Add(activationResults ...*ActivationResult) ActivationResultCollection {
for _, activationResult := range activationResults {
collection[activationResult.ComponentName()] = activationResult
}
return collection
}

// HasErrors tells whether the collection contains at least one activation result with error and respective code
func (collection ActivationResultCollection) HasErrors() bool {
for _, ar := range collection {
if ar.HasError() {
return true
}
}
return false
}

// HasPanics tells whether the collection contains at least one activation result with panic and respective code
func (collection ActivationResultCollection) HasPanics() bool {
for _, ar := range collection {
if ar.HasPanic() {
return true
}
}
return false
}

// HasActivatedComponents tells when at least one component in the cycle has activated
func (collection ActivationResultCollection) HasActivatedComponents() bool {
for _, ar := range collection {
if ar.Activated() {
return true
}
}
return false
}
76 changes: 76 additions & 0 deletions component/activation_result_collection_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package component

import (
"errors"
"github.com/stretchr/testify/assert"
"testing"
)

func TestActivationResultCollection_Add(t *testing.T) {
type args struct {
activationResults []*ActivationResult
}
tests := []struct {
name string
collection ActivationResultCollection
args args
assertions func(t *testing.T, collection ActivationResultCollection)
}{
{
name: "adding nothing to empty collection",
collection: NewActivationResultCollection(),
args: args{
activationResults: nil,
},
assertions: func(t *testing.T, collection ActivationResultCollection) {
assert.Len(t, collection, 0)
assert.False(t, collection.HasErrors())
assert.False(t, collection.HasPanics())
assert.False(t, collection.HasActivatedComponents())
},
},
{
name: "adding to empty collection",
collection: NewActivationResultCollection(),
args: args{
activationResults: []*ActivationResult{
NewComponent("c1").newActivationResultOK(),
NewComponent("c2").newActivationCodeReturnedError(errors.New("oops")),
},
},
assertions: func(t *testing.T, collection ActivationResultCollection) {
assert.Len(t, collection, 2)
assert.True(t, collection.HasActivatedComponents())
assert.True(t, collection.HasErrors())
assert.False(t, collection.HasPanics())
},
},
{
name: "adding to existing collection",
collection: NewActivationResultCollection().Add(
NewComponent("c1").newActivationResultOK(),
NewComponent("c2").newActivationResultOK(),
),
args: args{
activationResults: []*ActivationResult{
NewComponent("c4").newActivationCodeNoInput(),
NewComponent("c5").newActivationCodePanicked(errors.New("panic")),
},
},
assertions: func(t *testing.T, collection ActivationResultCollection) {
assert.Len(t, collection, 4)
assert.True(t, collection.HasPanics())
assert.False(t, collection.HasErrors())
assert.True(t, collection.HasActivatedComponents())
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tt.collection.Add(tt.args.activationResults...)
if tt.assertions != nil {
tt.assertions(t, tt.collection)
}
})
}
}
22 changes: 22 additions & 0 deletions component/collection.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package component

// ComponentCollection is a collection of components with useful methods
type Collection map[string]*Component

// NewComponentCollection creates empty collection
func NewComponentCollection() Collection {
return make(Collection)
}

// ByName returns a component by its name
func (collection Collection) ByName(name string) *Component {
return collection[name]
}

// Add adds new components to existing collection
func (collection Collection) Add(newComponents ...*Component) Collection {
for _, component := range newComponents {
collection[component.Name()] = component
}
return collection
}
109 changes: 109 additions & 0 deletions component/collection_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
package component

import (
"github.com/hovsep/fmesh/port"
"github.com/stretchr/testify/assert"
"reflect"
"testing"
)

func TestCollection_ByName(t *testing.T) {
type args struct {
name string
}
tests := []struct {
name string
components Collection
args args
want *Component
}{
{
name: "component found",
components: NewComponentCollection().Add(NewComponent("c1"), NewComponent("c2")),
args: args{
name: "c2",
},
want: &Component{
name: "c2",
description: "",
inputs: port.Collection{},
outputs: port.Collection{},
f: nil,
},
},
{
name: "component not found",
components: NewComponentCollection().Add(NewComponent("c1"), NewComponent("c2")),
args: args{
name: "c3",
},
want: nil,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := tt.components.ByName(tt.args.name); !reflect.DeepEqual(got, tt.want) {
t.Errorf("ByName() = %v, want %v", got, tt.want)
}
})
}
}

func TestCollection_Add(t *testing.T) {
type args struct {
components []*Component
}
tests := []struct {
name string
collection Collection
args args
assertions func(t *testing.T, collection Collection)
}{
{
name: "adding nothing to empty collection",
collection: NewComponentCollection(),
args: args{
components: nil,
},
assertions: func(t *testing.T, collection Collection) {
assert.Len(t, collection, 0)
},
},
{
name: "adding to empty collection",
collection: NewComponentCollection(),
args: args{
components: []*Component{NewComponent("c1"), NewComponent("c2")},
},
assertions: func(t *testing.T, collection Collection) {
assert.Len(t, collection, 2)
assert.NotNil(t, collection.ByName("c1"))
assert.NotNil(t, collection.ByName("c2"))
assert.Nil(t, collection.ByName("c999"))
},
},
{
name: "adding to existing collection",
collection: NewComponentCollection().Add(NewComponent("c1"), NewComponent("c2")),
args: args{
components: []*Component{NewComponent("c3"), NewComponent("c4")},
},
assertions: func(t *testing.T, collection Collection) {
assert.Len(t, collection, 4)
assert.NotNil(t, collection.ByName("c1"))
assert.NotNil(t, collection.ByName("c2"))
assert.NotNil(t, collection.ByName("c3"))
assert.NotNil(t, collection.ByName("c4"))
assert.Nil(t, collection.ByName("c999"))
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tt.collection.Add(tt.args.components...)
if tt.assertions != nil {
tt.assertions(t, tt.collection)
}
})
}
}
Loading

0 comments on commit 0dcb84f

Please sign in to comment.