Skip to content

Commit

Permalink
refactor(all): Revamped code base to extend on general Function inste…
Browse files Browse the repository at this point in the history
…ad of ErrorF
  • Loading branch information
protoman92 committed Mar 25, 2018
1 parent 4095a24 commit f5bbec4
Show file tree
Hide file tree
Showing 16 changed files with 236 additions and 197 deletions.
19 changes: 19 additions & 0 deletions compose/constant_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package compose

import (
"errors"
"time"
)

const (
delayTime = time.Duration(1e8)
retryCount = uint(10)

// This value should be returned by test Functions.
valueOp = 1
)

var (
// This error should be returned by test Functions.
errOp = errors.New("error")
)
10 changes: 3 additions & 7 deletions compose/doc.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
// Package compose contains utility higher-order functions to wrap normal
// functions.
//
// Naming conventions are:
// - J prefix: Represents Just.
// - M prefix: Represents Map.
// - F prefix: Represents FlatMap.
// Package compose contains higher-order functions to wrap normal functions to
// provide additional capabilities. It also contains function extensions that
// call these higher functions for easy chaining.
package compose
33 changes: 0 additions & 33 deletions compose/error.go

This file was deleted.

10 changes: 10 additions & 0 deletions compose/function.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package compose

// Function represents an operation that could return an error.
type Function func() (interface{}, error)

// Invoke is a convenience method to call a Function. Although it is the same
// as if we call the function normally, this may look nicer in a chain.
func (f Function) Invoke() (interface{}, error) {
return f()
}
24 changes: 24 additions & 0 deletions compose/functionF.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package compose

// FunctionF transforms a Function into another Function.
type FunctionF func(Function) Function

// Compose composes the functionalities of both FunctionF. We can use this to
// chain enhance a base Function without exposing implementation details.
func (ff FunctionF) Compose(selector FunctionF) FunctionF {
return func(f Function) Function {
return ff(selector(f))
}
}

// ComposeFn is similar to Compose, but it is more convenient when we deal with
// functions that return FunctionF.
func (ff FunctionF) ComposeFn(selectorFn func() FunctionF) FunctionF {
return ff.Compose(selectorFn())
}

// Wrap is a convenience method to invoke the wrap on a Function. This may look
// nice in a function chain.
func (ff FunctionF) Wrap(f Function) Function {
return ff(f)
}
24 changes: 12 additions & 12 deletions compose/error_test.go → compose/functionF_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,39 +7,39 @@ import (
func TestCompose(t *testing.T) {
published := 0

var retryF ErrorFF = Retry(retryCount)
retryF := RetryF(retryCount)

publishF := PublishError(func(err error) {
publishF := PublishF(func(value interface{}, err error) {
published++
})

errF := func() error {
return err
errF := func() (interface{}, error) {
return valueOp, errOp
}

/// When && Then 1
retryF.Compose(publishF).Compose(NoopError())(errF)()
retryF.Compose(publishF).ComposeFn(NoopF)(errF)()

if uint(published) != retryCount+1 {
t.Errorf("Expected %d, got %d", retryCount+1, published)
}

/// When && Then 2
published = 0
publishF.Compose(retryF).Compose(NoopError())(errF)()
publishF.Compose(retryF).ComposeFn(NoopF)(errF)()

if published != 1 {
t.Errorf("Expected %d, got %d", 1, published)
}
}

func BenchmarkComposition(b *testing.B) {
errF := func() error {
return err
errF := func() (interface{}, error) {
return valueOp, errOp
}

publishF := func(err error) {}
composeF := PublishError(publishF)
publishF := func(value interface{}, err error) {}
composeF := PublishF(publishF)

composed := composeF.
Compose(composeF).
Expand All @@ -53,8 +53,8 @@ func BenchmarkComposition(b *testing.B) {
}

func BenchmarkOrdinaryErrorF(b *testing.B) {
errF := func() error {
return err
errF := func() (interface{}, error) {
return valueOp, errOp
}

for i := 0; i < b.N; i++ {
Expand Down
13 changes: 13 additions & 0 deletions compose/noop.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package compose

// NoopF does nothing and simply returns the function.
func NoopF() FunctionF {
return func(f Function) Function {
return f
}
}

// Noop is a convenience function that calls the composable NoopF under the hood.
func (f Function) Noop() Function {
return NoopF().Wrap(f)
}
8 changes: 0 additions & 8 deletions compose/noopError.go

This file was deleted.

15 changes: 0 additions & 15 deletions compose/noopError_test.go

This file was deleted.

15 changes: 15 additions & 0 deletions compose/noop_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package compose

import "testing"

func TestNoop(t *testing.T) {
/// Setup
var errF Function = func() (interface{}, error) {
return valueOp, errOp
}

/// When & Then
if _, err := errF.Noop().Invoke(); err != errOp {
t.Errorf("Expected %v, got %v", errOp, err)
}
}
18 changes: 18 additions & 0 deletions compose/publish.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package compose

// PublishF publishes the result of a Function for side effects.
func PublishF(callback func(interface{}, error)) FunctionF {
return func(f Function) Function {
return func() (interface{}, error) {
value, err := f()
callback(value, err)
return value, err
}
}
}

// Publish is a convenience function that calls the composable PublishF under
// the hood.
func (f Function) Publish(callback func(interface{}, error)) Function {
return PublishF(callback).Wrap(f)
}
12 changes: 0 additions & 12 deletions compose/publishError.go

This file was deleted.

33 changes: 0 additions & 33 deletions compose/publishError_test.go

This file was deleted.

41 changes: 41 additions & 0 deletions compose/publish_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package compose

import (
"testing"
)

func TestPublish(t *testing.T) {
/// Setup
published := 0
var publishedValue interface{}
var publishedErr error

var errF Function = func() (interface{}, error) {
return valueOp, errOp
}

publishF := func(value interface{}, err error) {
published++
publishedValue = value
publishedErr = err
}

/// When & Then
value, err := errF.Publish(publishF).Retry(retryCount).Invoke()

if err != errOp || value != nil {
t.Errorf("Expected %v, got %v", errOp, err)
}

if publishedValue != valueOp {
t.Errorf("Expected %v, got %v", valueOp, publishedValue)
}

if publishedErr != errOp {
t.Errorf("Expected %v, got %v", errOp, publishedErr)
}

if uint(published) != retryCount+1 {
t.Errorf("Expected %v, got %v", retryCount+1, published)
}
}
Loading

0 comments on commit f5bbec4

Please sign in to comment.