Skip to content

Commit

Permalink
added unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Ompluscator committed Oct 16, 2022
1 parent 9f0dcda commit 805f24e
Show file tree
Hide file tree
Showing 16 changed files with 685 additions and 90 deletions.
10 changes: 10 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
language: go

go:
- 1.18
- stable
- master

script:
- go test -v ./...
- go test -v -race ./...
17 changes: 14 additions & 3 deletions binding.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,13 +73,13 @@ func AsReference[T any, S *R, R any]() BindingSource[T] {
}
}

type ProviderBinding[S any] func() (S, error)
type ProviderMethod[S any] func() (S, error)

func (b ProviderBinding[S]) Instance(bool) (interface{}, error) {
func (b ProviderMethod[S]) Instance(bool) (interface{}, error) {
return b()
}

func AsProvider[T any, S any](provider ProviderBinding[S]) BindingSource[T] {
func AsProvider[T any, S any](provider ProviderMethod[S]) BindingSource[T] {
return &bindingSource[T]{
binding: provider,
keySource: baseKeySource[T]{},
Expand Down Expand Up @@ -162,3 +162,14 @@ func WithAnnotation(annotation string) BindingOption {
},
}
}

func WithContainer(container Container) BindingOption {
return &bindingOption{
bindingFunc: func(binding Binding) (Binding, error) {
return binding, nil
},
keyOption: &containerKeyOption{
container: container,
},
}
}
26 changes: 22 additions & 4 deletions binding_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -282,8 +282,8 @@ func TestAsReference(t *testing.T) {
}
}

func Test_ProviderBinding_Instance(t *testing.T) {
var stringBinding ProviderBinding[string] = func() (string, error) {
func Test_ProviderMethod_Instance(t *testing.T) {
var stringBinding ProviderMethod[string] = func() (string, error) {
return "value", nil
}
result, err := stringBinding.Instance(true)
Expand All @@ -294,7 +294,7 @@ func Test_ProviderBinding_Instance(t *testing.T) {
t.Errorf(`expected reference to empty string, got: %v`, result)
}

var intBinding ProviderBinding[*int] = func() (*int, error) {
var intBinding ProviderMethod[*int] = func() (*int, error) {
value := 10
return &value, nil
}
Expand All @@ -307,7 +307,7 @@ func Test_ProviderBinding_Instance(t *testing.T) {
t.Errorf(`expected reference to 0, got: %v`, result)
}

var structBinding ProviderBinding[*testStruct] = func() (*testStruct, error) {
var structBinding ProviderMethod[*testStruct] = func() (*testStruct, error) {
return &testStruct{
a: "a",
b: 5,
Expand Down Expand Up @@ -545,3 +545,21 @@ func TestWithAnnotation(t *testing.T) {
t.Error("binding options are different")
}
}

func TestWithContainer(t *testing.T) {
result := WithContainer(Container{
"first": nil,
})
if !reflect.DeepEqual(&containerKeyOption{
container: Container{
"first": nil,
},
}, result.(*bindingOption).keyOption) {
t.Error("containerKeyOption does not contain the right value")
}

result = WithContainer(nil)
if !reflect.DeepEqual(new(containerKeyOption), result.(*bindingOption).keyOption) {
t.Error("containerKeyOption does not contain the right value")
}
}
72 changes: 72 additions & 0 deletions examples/annotation_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package examples

import (
"fmt"
"github.com/ompluscator/genjector"
"testing"
)

type AnnotationInterface interface {
String() string
}

type AnnotationStruct struct {
value string
}

func (s *AnnotationStruct) Init() {
firstChild := genjector.MustInitialize[*AnnotationChildStruct](genjector.AnnotatedWith("first"))
secondChild := genjector.MustInitialize[*AnnotationChildStruct](genjector.AnnotatedWith("second"))
s.value = fmt.Sprintf("%s | %s", firstChild.value, secondChild.value)
}

func (s *AnnotationStruct) String() string {
return s.value
}

type AnnotationChildStruct struct {
value string
}

func (s *AnnotationChildStruct) Init() {
s.value = "value provided inside the AnnotationChildStruct"
}

func TestAsAnnotation(t *testing.T) {
t.Run("Take values from inner 2 child objects defined with proper annotation", func(t *testing.T) {
genjector.Clean()

err := genjector.Bind(genjector.AsReference[AnnotationInterface, *AnnotationStruct]())
if err != nil {
t.Error("binding should not cause an error")
}

err = genjector.Bind(genjector.AsProvider[*AnnotationChildStruct](func() (*AnnotationChildStruct, error) {
return &AnnotationChildStruct{
value: "value from the first child",
}, nil
}), genjector.WithAnnotation("first"))
if err != nil {
t.Error("binding should not cause an error")
}

err = genjector.Bind(genjector.AsProvider[*AnnotationChildStruct](func() (*AnnotationChildStruct, error) {
return &AnnotationChildStruct{
value: "value from the second child",
}, nil
}), genjector.WithAnnotation("second"))
if err != nil {
t.Error("binding should not cause an error")
}

instance, err := genjector.Initialize[AnnotationInterface]()
if err != nil {
t.Error("initialization should not cause an error")
}

value := instance.String()
if value != "value from the first child | value from the second child" {
t.Errorf(`unexpected value received: "%s"`, value)
}
})
}
56 changes: 56 additions & 0 deletions examples/container_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package examples

import (
"github.com/ompluscator/genjector"
"testing"
)

type ContainerInterface interface {
String() string
}

type ContainerStruct struct {
value string
}

func (s *ContainerStruct) Init() {
s.value = "value provided inside the ContainerStruct"
}

func (s *ContainerStruct) String() string {
return s.value
}

func TestAsContainer(t *testing.T) {
t.Run("Store binding inside the customer container and not the global one", func(t *testing.T) {
genjector.Clean()

customContainer := genjector.NewContainer()

err := genjector.Bind(
genjector.AsReference[ContainerInterface, *ContainerStruct](),
genjector.WithContainer(customContainer),
)
if err != nil {
t.Error("binding should not cause an error")
}

instance, err := genjector.Initialize[ContainerInterface]()
if err == nil {
t.Error("expected an error, but got nil")
}
if instance != nil {
t.Errorf(`unexpected instance received: "%s"`, instance)
}

instance, err = genjector.Initialize[ContainerInterface](genjector.WithContainer(customContainer))
if err != nil {
t.Error("initialization should not cause an error")
}

value := instance.String()
if value != "value provided inside the ContainerStruct" {
t.Errorf(`unexpected value received: "%s"`, value)
}
})
}
67 changes: 67 additions & 0 deletions examples/instance_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package examples

import (
"testing"

"github.com/ompluscator/genjector"
)

type InstanceInterface interface {
String() string
}

type InstanceStruct struct {
value string
}

func (s *InstanceStruct) Init() {
s.value = "value provided inside the InstanceStruct"
}

func (s *InstanceStruct) String() string {
return s.value
}

func TestAsInstance(t *testing.T) {
t.Run("Bind a reference to a struct as an implementation for an interface", func(t *testing.T) {
genjector.Clean()

err := genjector.Bind(genjector.AsInstance[InstanceInterface](&InstanceStruct{
value: "value provided inside the Test method",
}))
if err != nil {
t.Error("binding should not cause an error")
}

instance, err := genjector.Initialize[InstanceInterface]()
if err != nil {
t.Error("initialization should not cause an error")
}

value := instance.String()
if value != "value provided inside the Test method" {
t.Errorf(`unexpected value received: "%s"`, value)
}
})

t.Run("Bind a reference to a struct as an implementation for the reference of that struct", func(t *testing.T) {
genjector.Clean()

err := genjector.Bind(genjector.AsInstance[*InstanceStruct](&InstanceStruct{
value: "value provided inside the Test method",
}))
if err != nil {
t.Error("binding should not cause an error")
}

instance, err := genjector.Initialize[*InstanceStruct]()
if err != nil {
t.Error("initialization should not cause an error")
}

value := instance.String()
if value != "value provided inside the Test method" {
t.Errorf(`unexpected value received: "%s"`, value)
}
})
}
75 changes: 75 additions & 0 deletions examples/map_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package examples

import (
"github.com/ompluscator/genjector"
"testing"
)

type MapInterface interface {
String() string
}

type MapStruct struct {
value string
}

func (s *MapStruct) Init() {
s.value = "value provided inside the MapStruct"
}

func (s *MapStruct) String() string {
return s.value
}

func TestAsMap(t *testing.T) {
t.Run("Bind multiple references to a struct as an implementations for an interface", func(t *testing.T) {
genjector.Clean()

err := genjector.Bind(
genjector.InMap("first", genjector.AsReference[MapInterface, *MapStruct]()),
)
if err != nil {
t.Error("binding should not cause an error")
}

err = genjector.Bind(
genjector.InMap("second", genjector.AsProvider[MapInterface](func() (*MapStruct, error) {
return &MapStruct{
value: "value provided inside the ProviderMethod",
}, nil
})),
)
if err != nil {
t.Error("binding should not cause an error")
}

err = genjector.Bind(
genjector.InMap("third", genjector.AsInstance[MapInterface](&MapStruct{
value: "value provided inside the Test method",
})),
)
if err != nil {
t.Error("binding should not cause an error")
}

instance, err := genjector.Initialize[map[string]MapInterface]()
if err != nil {
t.Error("initialization should not cause an error")
}

value := instance["first"].String()
if value != "value provided inside the MapStruct" {
t.Errorf(`unexpected value received: "%s"`, value)
}

value = instance["second"].String()
if value != "value provided inside the ProviderMethod" {
t.Errorf(`unexpected value received: "%s"`, value)
}

value = instance["third"].String()
if value != "value provided inside the Test method" {
t.Errorf(`unexpected value received: "%s"`, value)
}
})
}
Loading

0 comments on commit 805f24e

Please sign in to comment.