Skip to content

[API-858] Add Unit Tests to Baseline Code #2

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

Merged
merged 14 commits into from
Oct 10, 2017
Merged
Show file tree
Hide file tree
Changes from 9 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
3 changes: 3 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ jobs:

steps:
- checkout
- run: ln -s ./ /usr/local/go/src/github.com/percolate/shisa
- run: ln -s ./ /go/src/github.com/percolate/shisa
- run: make test
- run: sbin/codecov

mdl:
docker:
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
*.o
*.a
*.so
build

# go noise
*.[568vq]
Expand All @@ -23,3 +24,4 @@ _test/

# editor noise
*~
.idea
22 changes: 18 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ TOP_DIR := $(abspath $(dir $(lastword $(MAKEFILE_LIST))))
DIAGRAM_DIR := doc/diagram
DIAGRAMS := $(DIAGRAM_DIR)/architecture.png

BUILD_DIR := build
COVERAGE_DIR := $(BUILD_DIR)/coverage

SHISA_PKGS := $(shell go list ./... | grep -Ev 'examples|test')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we would want to have test coverage for the test helpers. For example, the net/http/httptest package has test for those helpers.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, but as we just talked about, subpackages get tricky to test with the way we're generating the coverage reports

image

SHISA_TEST_PKGS := $(addprefix coverage/,$(SHISA_PKGS))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you have a chance to look into generating a unified coverage report that includes cross-package coverage? We discussed taking some examples from this golang issue

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as we just discussed, it might make sense to handle incidental coverage in a subsequent PR


all: test

doc/diagram/%.png: doc/%.dot
Expand All @@ -15,16 +21,24 @@ doc/diagram/%.png: doc/%.dot

doc: $(DIAGRAMS)

$(BUILD_DIR):
@mkdir -p $@

$(COVERAGE_DIR):
@mkdir -p $@

clean:
rm -rf pkg
rm -rf $(BUILD_DIR)

fmt:
go fmt ./...

vet:
go vet ./...

test: fmt vet
go test -v ./...
test: ${BUILD_DIR} ${SHISA_TEST_PKGS}

coverage/%: $(BUILD_DIR) $(COVERAGE_DIR)
cd $(TOP_DIR)/$(@F) && go test -v -coverprofile=$(TOP_DIR)/$(COVERAGE_DIR)/$(@F)_coverage.out -covermode=atomic

.PHONY: clean doc vet fmt
.PHONY: clean doc vet fmt test
1 change: 1 addition & 0 deletions context/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const (
ActorKey = "ContextActorKey"
)

//go:generate charlatan -interfaces=Context -output=./contexttest/charlatancontext.go /usr/local/go/src/context/context.go
type Context struct {
context.Context
RequestID string
Expand Down
272 changes: 272 additions & 0 deletions context/context_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,272 @@
package context

import (
"context"
"testing"
"time"

"errors"
"github.com/percolate/shisa/context/contexttest"
"github.com/percolate/shisa/log/logtest"
"github.com/percolate/shisa/models/modelstest"
"github.com/stretchr/testify/assert"
)

var _ context.Context = &contexttest.FakeContext{}

func getContextForLogging(requestID string, logger *logtest.FakeLogger) *Context {
actor := &modelstest.FakeUser{}
parent := &contexttest.FakeContext{}

c := New(parent, requestID, actor, logger)

return c
}

func getContextForParent(parent context.Context) *Context {
actor := &modelstest.FakeUser{}
logger := &logtest.FakeLogger{}

c := New(parent, "999999", actor, logger)

return c
}

func TestNew(t *testing.T) {
actor := &modelstest.FakeUser{}
logger := &logtest.FakeLogger{}
parent := &contexttest.FakeContext{}
id := "555"

c := New(parent, id, actor, logger)

assert.Equal(t, parent, c.Context)
assert.Equal(t, id, c.RequestID)
assert.Equal(t, actor, c.Actor)
assert.Equal(t, logger, c.Logger)
}

func TestInfo(t *testing.T) {
requestID := "555"
message := "Hello test"

logger := &logtest.FakeLogger{
InfoHook: func(requestID string, message string) {},
}

c := getContextForLogging(requestID, logger)

c.Info(message)

assert.Equal(t, len(logger.InfoCalls), 1)

invocation := logger.InfoCalls[0]

assert.Equal(t, invocation.Parameters.RequestID, requestID)
assert.Equal(t, invocation.Parameters.Message, message)
}

func TestInfof(t *testing.T) {
requestID := "555"
format := "Hello test %s"

// lol no generics
s := []string{"arg"}
args := make([]interface{}, len(s))
for i, v := range s {
args[i] = v
}

logger := &logtest.FakeLogger{
InfofHook: func(requestID string, format string, args ...interface{}) {},
}

c := getContextForLogging(requestID, logger)

c.Infof(format, args...)

assert.Equal(t, len(logger.InfofCalls), 1)

invocation := logger.InfofCalls[0]

assert.Equal(t, invocation.Parameters.RequestID, requestID)
assert.Equal(t, invocation.Parameters.Format, format)
assert.Equal(t, invocation.Parameters.Args, args)
}

func TestError(t *testing.T) {
requestID := "555"
message := "Hello test"

logger := &logtest.FakeLogger{
ErrorHook: func(requestID string, message string) {},
}

c := getContextForLogging(requestID, logger)

c.Error(message)

assert.Equal(t, len(logger.ErrorCalls), 1)

invocation := logger.ErrorCalls[0]

assert.Equal(t, invocation.Parameters.RequestID, requestID)
assert.Equal(t, invocation.Parameters.Message, message)
}

func TestErrorf(t *testing.T) {
requestID := "555"
format := "Hello test %s"

// lol no generics
s := []string{"arg"}
args := make([]interface{}, len(s))
for i, v := range s {
args[i] = v
}

logger := &logtest.FakeLogger{
ErrorfHook: func(requestID string, format string, args ...interface{}) {},
}

c := getContextForLogging(requestID, logger)

c.Errorf(format, args...)

assert.Equal(t, len(logger.ErrorfCalls), 1)

invocation := logger.ErrorfCalls[0]

assert.Equal(t, invocation.Parameters.RequestID, requestID)
assert.Equal(t, invocation.Parameters.Format, format)
assert.Equal(t, invocation.Parameters.Args, args)
}

func TestTrace(t *testing.T) {
requestID := "555"
message := "Hello test"

logger := &logtest.FakeLogger{
TraceHook: func(requestID string, message string) {},
}

c := getContextForLogging(requestID, logger)

c.Trace(message)

assert.Equal(t, len(logger.TraceCalls), 1)

invocation := logger.TraceCalls[0]

assert.Equal(t, invocation.Parameters.RequestID, requestID)
assert.Equal(t, invocation.Parameters.Message, message)
}

func TestTracef(t *testing.T) {
requestID := "555"
format := "Hello test %s"

// lol no generics
s := []string{"arg"}
args := make([]interface{}, len(s))
for i, v := range s {
args[i] = v
}

logger := &logtest.FakeLogger{
TracefHook: func(requestID string, format string, args ...interface{}) {},
}

c := getContextForLogging(requestID, logger)

c.Tracef(format, args...)

assert.Equal(t, len(logger.TracefCalls), 1)

invocation := logger.TracefCalls[0]

assert.Equal(t, invocation.Parameters.RequestID, requestID)
assert.Equal(t, invocation.Parameters.Format, format)
assert.Equal(t, invocation.Parameters.Args, args)
}

func TestDeadline(t *testing.T) {
deadline := time.Time{}
ok := false

parent := &contexttest.FakeContext{
DeadlineHook: func() (deadline time.Time, ok bool) {
return deadline, ok
},
}
c := getContextForParent(parent)

d, y := c.Deadline()

assert.Equal(t, len(parent.DeadlineCalls), 1)

assert.Equal(t, d, deadline)
assert.Equal(t, y, ok)

}

func TestDone(t *testing.T) {
channelval := struct{}{}
parent := &contexttest.FakeContext{
DoneHook: func() (ret0 <-chan struct{}) {
d := make(chan struct{})
go func() {
d <- channelval
close(d)
}()
return d
},
}
c := getContextForParent(parent)

result := <-c.Done()

assert.Equal(t, len(parent.DoneCalls), 1)
assert.Equal(t, result, channelval)
}

func TestErr(t *testing.T) {
err := errors.New("New Error")
parent := &contexttest.FakeContext{
ErrHook: func() (ret0 error) {
return err
},
}
c := getContextForParent(parent)

result := c.Err()

assert.Equal(t, len(parent.ErrCalls), 1)
assert.Equal(t, result, err)
}

func TestValueID(t *testing.T) {
pkey := "ParentKey"
pval := true
parent := &contexttest.FakeContext{
ValueHook: func(key interface{}) (ret0 interface{}) {
return pval
},
}

c := getContextForParent(parent)

idVal := c.Value(IDKey)
actorVal := c.Value(ActorKey)
loggerVal := c.Value(LoggerKey)
parentVal := c.Value(pkey)

assert.Equal(t, idVal, c.RequestID)
assert.Equal(t, actorVal, c.Actor)
assert.Equal(t, loggerVal, c.Logger)

assert.Equal(t, len(parent.ValueCalls), 1)
invocation := parent.ValueCalls[0]
assert.Equal(t, invocation.Parameters.Key, pkey)
assert.Equal(t, invocation.Results.Ret0, parentVal)
}
Loading