Switch to newest pegomock library (#205)

This commit is contained in:
Luke Kysow
2017-11-19 22:41:43 -08:00
committed by GitHub
parent ff5183642f
commit acdf771ce7
95 changed files with 1395 additions and 190 deletions

2
Gopkg.lock generated
View File

@@ -161,7 +161,7 @@
branch = "master"
name = "github.com/petergtz/pegomock"
packages = [".","internal/verify"]
revision = "b99e34d8f73c46cb5e7fef35963a0b0bb89887eb"
revision = "e34a58f05f9a8ea0cd71912e02a4b08e1128aa81"
[[projects]]
name = "github.com/pkg/errors"

View File

@@ -28,6 +28,12 @@ build-service: ## Build the main Go service
go-generate: ## Run go generate in all packages
go generate $(PKG)
regen-mocks: ## Delete all mocks and then run go generate to regen them
find . -type f | grep mocks/mock | grep -v vendor | xargs rm
@# not using $(PKG) here because that it includes directories that have now
@# been deleted, causing go generate to fail.
go generate $$(go list ./... | grep -v e2e | grep -v vendor | grep -v static)
test: ## Run tests
go test $(PKG)

View File

@@ -12,19 +12,19 @@ import (
"github.com/pkg/errors"
)
//go:generate pegomock generate --use-experimental-model-gen --package mocks -o mocks/mock_command_runner.go CommandRunner
//go:generate pegomock generate -m --use-experimental-model-gen --package mocks -o mocks/mock_command_runner.go CommandRunner
type CommandRunner interface {
ExecuteCommand(baseRepo models.Repo, headRepo models.Repo, user models.User, pullNum int, cmd *Command, vcsHost vcs.Host)
}
//go:generate pegomock generate --use-experimental-model-gen --package mocks -o mocks/mock_github_pull_getter.go GithubPullGetter
//go:generate pegomock generate -m --use-experimental-model-gen --package mocks -o mocks/mock_github_pull_getter.go GithubPullGetter
type GithubPullGetter interface {
GetPullRequest(repo models.Repo, pullNum int) (*github.PullRequest, error)
}
//go:generate pegomock generate --use-experimental-model-gen --package mocks -o mocks/mock_gitlab_merge_request_getter.go GitlabMergeRequestGetter
//go:generate pegomock generate -m --use-experimental-model-gen --package mocks -o mocks/mock_gitlab_merge_request_getter.go GitlabMergeRequestGetter
type GitlabMergeRequestGetter interface {
GetMergeRequest(repoFullName string, pullNum int) (*gitlab.MergeRequest, error)

View File

@@ -4,13 +4,13 @@ import (
"bytes"
"errors"
"log"
"reflect"
"strings"
"testing"
"github.com/google/go-github/github"
"github.com/hootsuite/atlantis/server/events"
"github.com/hootsuite/atlantis/server/events/mocks"
"github.com/hootsuite/atlantis/server/events/mocks/matchers"
"github.com/hootsuite/atlantis/server/events/models"
"github.com/hootsuite/atlantis/server/events/models/fixtures"
"github.com/hootsuite/atlantis/server/events/vcs"
@@ -66,7 +66,7 @@ func TestExecuteCommand_LogPanics(t *testing.T) {
setup(t)
When(ghStatus.Update(fixtures.Repo, fixtures.Pull, vcs.Pending, nil, vcs.Github)).ThenPanic("panic")
ch.ExecuteCommand(fixtures.Repo, fixtures.Repo, fixtures.User, 1, nil, vcs.Github)
_, _, comment, _ := vcsClient.VerifyWasCalledOnce().CreateComment(AnyRepo(), AnyPullRequest(), AnyString(), AnyVCSHost()).GetCapturedArguments()
_, _, comment, _ := vcsClient.VerifyWasCalledOnce().CreateComment(matchers.AnyModelsRepo(), matchers.AnyModelsPullRequest(), AnyString(), matchers.AnyVcsHost()).GetCapturedArguments()
Assert(t, strings.Contains(comment, "Error: goroutine panic"), "comment should be about a goroutine panic")
}
@@ -148,7 +148,7 @@ func TestExecuteCommand_EnvLocked(t *testing.T) {
" command that is running for this pull request." +
" Wait until the previous command is complete and try again."
ghStatus.VerifyWasCalledOnce().Update(fixtures.Repo, fixtures.Pull, vcs.Pending, &cmd, vcs.Github)
_, response := ghStatus.VerifyWasCalledOnce().UpdateProjectResult(AnyCommandContext(), AnyCommandResponse()).GetCapturedArguments()
_, response := ghStatus.VerifyWasCalledOnce().UpdateProjectResult(matchers.AnyPtrToEventsCommandContext(), matchers.AnyEventsCommandResponse()).GetCapturedArguments()
Equals(t, msg, response.Failure)
vcsClient.VerifyWasCalledOnce().CreateComment(fixtures.Repo, fixtures.Pull,
"**Plan Failed**: "+msg+"\n\n", vcs.Github)
@@ -171,34 +171,19 @@ func TestExecuteCommand_FullRun(t *testing.T) {
When(envLocker.TryLock(fixtures.Repo.FullName, cmd.Environment, fixtures.Pull.Num)).ThenReturn(true)
switch c {
case events.Help:
When(helper.Execute(AnyCommandContext())).ThenReturn(cmdResponse)
When(helper.Execute(matchers.AnyPtrToEventsCommandContext())).ThenReturn(cmdResponse)
case events.Plan:
When(planner.Execute(AnyCommandContext())).ThenReturn(cmdResponse)
When(planner.Execute(matchers.AnyPtrToEventsCommandContext())).ThenReturn(cmdResponse)
case events.Apply:
When(applier.Execute(AnyCommandContext())).ThenReturn(cmdResponse)
When(applier.Execute(matchers.AnyPtrToEventsCommandContext())).ThenReturn(cmdResponse)
}
ch.ExecuteCommand(fixtures.Repo, fixtures.Repo, fixtures.User, fixtures.Pull.Num, &cmd, vcs.Github)
ghStatus.VerifyWasCalledOnce().Update(fixtures.Repo, fixtures.Pull, vcs.Pending, &cmd, vcs.Github)
_, response := ghStatus.VerifyWasCalledOnce().UpdateProjectResult(AnyCommandContext(), AnyCommandResponse()).GetCapturedArguments()
_, response := ghStatus.VerifyWasCalledOnce().UpdateProjectResult(matchers.AnyPtrToEventsCommandContext(), matchers.AnyEventsCommandResponse()).GetCapturedArguments()
Equals(t, cmdResponse, response)
vcsClient.VerifyWasCalledOnce().CreateComment(AnyRepo(), AnyPullRequest(), AnyString(), AnyVCSHost())
vcsClient.VerifyWasCalledOnce().CreateComment(matchers.AnyModelsRepo(), matchers.AnyModelsPullRequest(), AnyString(), matchers.AnyVcsHost())
envLocker.VerifyWasCalledOnce().Unlock(fixtures.Repo.FullName, cmd.Environment, fixtures.Pull.Num)
}
}
func AnyCommandContext() *events.CommandContext {
RegisterMatcher(NewAnyMatcher(reflect.TypeOf(&events.CommandContext{})))
return &events.CommandContext{}
}
func AnyVCSHost() vcs.Host {
RegisterMatcher(NewAnyMatcher(reflect.TypeOf(vcs.Github)))
return vcs.Github
}
func AnyCommandResponse() events.CommandResponse {
RegisterMatcher(NewAnyMatcher(reflect.TypeOf(events.CommandResponse{})))
return events.CommandResponse{}
}

View File

@@ -8,7 +8,7 @@ import (
"github.com/hootsuite/atlantis/server/events/vcs"
)
//go:generate pegomock generate --use-experimental-model-gen --package mocks -o mocks/mock_commit_status_updater.go CommitStatusUpdater
//go:generate pegomock generate -m --use-experimental-model-gen --package mocks -o mocks/mock_commit_status_updater.go CommitStatusUpdater
type CommitStatusUpdater interface {
Update(repo models.Repo, pull models.PullRequest, status vcs.CommitStatus, cmd *Command, host vcs.Host) error

View File

@@ -5,7 +5,7 @@ import (
"sync"
)
//go:generate pegomock generate --use-experimental-model-gen --package mocks -o mocks/mock_env_locker.go EnvLocker
//go:generate pegomock generate -m --use-experimental-model-gen --package mocks -o mocks/mock_env_locker.go EnvLocker
type EnvLocker interface {
TryLock(repoFullName string, env string, pullNum int) bool

View File

@@ -13,7 +13,7 @@ import (
const gitlabPullOpened = "opened"
//go:generate pegomock generate --use-experimental-model-gen --package mocks -o mocks/mock_event_parsing.go EventParsing
//go:generate pegomock generate -m --use-experimental-model-gen --package mocks -o mocks/mock_event_parsing.go EventParsing
type Command struct {
Name CommandName

View File

@@ -1,6 +1,6 @@
package events
//go:generate pegomock generate --use-experimental-model-gen --package mocks -o mocks/mock_executor.go Executor
//go:generate pegomock generate -m --use-experimental-model-gen --package mocks -o mocks/mock_executor.go Executor
type Executor interface {
Execute(ctx *CommandContext) CommandResponse

View File

@@ -10,7 +10,7 @@ import (
"github.com/hootsuite/atlantis/server/events/models"
)
//go:generate pegomock generate --use-experimental-model-gen --package mocks -o mocks/mock_backend.go Backend
//go:generate pegomock generate -m --use-experimental-model-gen --package mocks -o mocks/mock_backend.go Backend
// Backend is an implementation of the locking API we require.
type Backend interface {
@@ -36,7 +36,7 @@ type Client struct {
backend Backend
}
//go:generate pegomock generate --use-experimental-model-gen --package mocks -o mocks/mock_locker.go Locker
//go:generate pegomock generate -m --use-experimental-model-gen --package mocks -o mocks/mock_locker.go Locker
type Locker interface {
TryLock(p models.Project, env string, pull models.PullRequest, user models.User) (TryLockResponse, error)

View File

@@ -5,11 +5,11 @@ import (
"testing"
"time"
"reflect"
"strings"
"github.com/hootsuite/atlantis/server/events/locking"
"github.com/hootsuite/atlantis/server/events/locking/mocks"
"github.com/hootsuite/atlantis/server/events/locking/mocks/matchers"
"github.com/hootsuite/atlantis/server/events/models"
. "github.com/hootsuite/atlantis/testing"
. "github.com/petergtz/pegomock"
@@ -26,7 +26,7 @@ var pl = models.ProjectLock{Project: project, Pull: pull, User: user, Env: env,
func TestTryLock_Err(t *testing.T) {
RegisterMockTestingT(t)
backend := mocks.NewMockBackend()
When(backend.TryLock(AnyProjectLock())).ThenReturn(false, models.ProjectLock{}, expectedErr)
When(backend.TryLock(matchers.AnyModelsProjectLock())).ThenReturn(false, models.ProjectLock{}, expectedErr)
t.Log("when the backend returns an error, TryLock should return that error")
l := locking.NewClient(backend)
_, err := l.TryLock(project, env, pull, user)
@@ -37,7 +37,7 @@ func TestTryLock_Success(t *testing.T) {
RegisterMockTestingT(t)
currLock := models.ProjectLock{}
backend := mocks.NewMockBackend()
When(backend.TryLock(AnyProjectLock())).ThenReturn(true, currLock, nil)
When(backend.TryLock(matchers.AnyModelsProjectLock())).ThenReturn(true, currLock, nil)
l := locking.NewClient(backend)
r, err := l.TryLock(project, env, pull, user)
Ok(t, err)
@@ -57,7 +57,7 @@ func TestUnlock_InvalidKey(t *testing.T) {
func TestUnlock_Err(t *testing.T) {
RegisterMockTestingT(t)
backend := mocks.NewMockBackend()
When(backend.Unlock(AnyProject(), AnyString())).ThenReturn(nil, expectedErr)
When(backend.Unlock(matchers.AnyModelsProject(), AnyString())).ThenReturn(nil, expectedErr)
l := locking.NewClient(backend)
_, err := l.Unlock("owner/repo/path/env")
Equals(t, err, err)
@@ -67,7 +67,7 @@ func TestUnlock_Err(t *testing.T) {
func TestUnlock(t *testing.T) {
RegisterMockTestingT(t)
backend := mocks.NewMockBackend()
When(backend.Unlock(AnyProject(), AnyString())).ThenReturn(&pl, nil)
When(backend.Unlock(matchers.AnyModelsProject(), AnyString())).ThenReturn(&pl, nil)
l := locking.NewClient(backend)
lock, err := l.Unlock("owner/repo/path/env")
Ok(t, err)
@@ -131,13 +131,3 @@ func TestGetLock(t *testing.T) {
Ok(t, err)
Equals(t, &pl, lock)
}
func AnyProjectLock() models.ProjectLock {
RegisterMatcher(NewAnyMatcher(reflect.TypeOf(models.ProjectLock{})))
return models.ProjectLock{}
}
func AnyProject() models.Project {
RegisterMatcher(NewAnyMatcher(reflect.TypeOf(models.Project{})))
return models.Project{}
}

View File

@@ -0,0 +1,20 @@
package matchers
import (
"reflect"
locking "github.com/hootsuite/atlantis/server/events/locking"
"github.com/petergtz/pegomock"
)
func AnyLockingTryLockResponse() locking.TryLockResponse {
pegomock.RegisterMatcher(pegomock.NewAnyMatcher(reflect.TypeOf((*(locking.TryLockResponse))(nil)).Elem()))
var nullValue locking.TryLockResponse
return nullValue
}
func EqLockingTryLockResponse(value locking.TryLockResponse) locking.TryLockResponse {
pegomock.RegisterMatcher(&pegomock.EqMatcher{Value: value})
var nullValue locking.TryLockResponse
return nullValue
}

View File

@@ -0,0 +1,21 @@
package matchers
import (
"reflect"
"github.com/petergtz/pegomock"
models "github.com/hootsuite/atlantis/server/events/models"
)
func AnyMapOfStringToModelsProjectLock() map[string]models.ProjectLock {
pegomock.RegisterMatcher(pegomock.NewAnyMatcher(reflect.TypeOf((*(map[string]models.ProjectLock))(nil)).Elem()))
var nullValue map[string]models.ProjectLock
return nullValue
}
func EqMapOfStringToModelsProjectLock(value map[string]models.ProjectLock) map[string]models.ProjectLock {
pegomock.RegisterMatcher(&pegomock.EqMatcher{Value: value})
var nullValue map[string]models.ProjectLock
return nullValue
}

View File

@@ -0,0 +1,20 @@
package matchers
import (
"reflect"
models "github.com/hootsuite/atlantis/server/events/models"
"github.com/petergtz/pegomock"
)
func AnyModelsProject() models.Project {
pegomock.RegisterMatcher(pegomock.NewAnyMatcher(reflect.TypeOf((*(models.Project))(nil)).Elem()))
var nullValue models.Project
return nullValue
}
func EqModelsProject(value models.Project) models.Project {
pegomock.RegisterMatcher(&pegomock.EqMatcher{Value: value})
var nullValue models.Project
return nullValue
}

View File

@@ -0,0 +1,20 @@
package matchers
import (
"reflect"
models "github.com/hootsuite/atlantis/server/events/models"
"github.com/petergtz/pegomock"
)
func AnyModelsProjectLock() models.ProjectLock {
pegomock.RegisterMatcher(pegomock.NewAnyMatcher(reflect.TypeOf((*(models.ProjectLock))(nil)).Elem()))
var nullValue models.ProjectLock
return nullValue
}
func EqModelsProjectLock(value models.ProjectLock) models.ProjectLock {
pegomock.RegisterMatcher(&pegomock.EqMatcher{Value: value})
var nullValue models.ProjectLock
return nullValue
}

View File

@@ -0,0 +1,20 @@
package matchers
import (
"reflect"
models "github.com/hootsuite/atlantis/server/events/models"
"github.com/petergtz/pegomock"
)
func AnyModelsPullRequest() models.PullRequest {
pegomock.RegisterMatcher(pegomock.NewAnyMatcher(reflect.TypeOf((*(models.PullRequest))(nil)).Elem()))
var nullValue models.PullRequest
return nullValue
}
func EqModelsPullRequest(value models.PullRequest) models.PullRequest {
pegomock.RegisterMatcher(&pegomock.EqMatcher{Value: value})
var nullValue models.PullRequest
return nullValue
}

View File

@@ -0,0 +1,20 @@
package matchers
import (
"reflect"
models "github.com/hootsuite/atlantis/server/events/models"
"github.com/petergtz/pegomock"
)
func AnyModelsUser() models.User {
pegomock.RegisterMatcher(pegomock.NewAnyMatcher(reflect.TypeOf((*(models.User))(nil)).Elem()))
var nullValue models.User
return nullValue
}
func EqModelsUser(value models.User) models.User {
pegomock.RegisterMatcher(&pegomock.EqMatcher{Value: value})
var nullValue models.User
return nullValue
}

View File

@@ -0,0 +1,20 @@
package matchers
import (
"reflect"
models "github.com/hootsuite/atlantis/server/events/models"
"github.com/petergtz/pegomock"
)
func AnyPtrToModelsProjectLock() *models.ProjectLock {
pegomock.RegisterMatcher(pegomock.NewAnyMatcher(reflect.TypeOf((*(*models.ProjectLock))(nil)).Elem()))
var nullValue *models.ProjectLock
return nullValue
}
func EqPtrToModelsProjectLock(value *models.ProjectLock) *models.ProjectLock {
pegomock.RegisterMatcher(&pegomock.EqMatcher{Value: value})
var nullValue *models.ProjectLock
return nullValue
}

View File

@@ -0,0 +1,20 @@
package matchers
import (
"reflect"
models "github.com/hootsuite/atlantis/server/events/models"
"github.com/petergtz/pegomock"
)
func AnySliceOfModelsProjectLock() []models.ProjectLock {
pegomock.RegisterMatcher(pegomock.NewAnyMatcher(reflect.TypeOf((*([]models.ProjectLock))(nil)).Elem()))
var nullValue []models.ProjectLock
return nullValue
}
func EqSliceOfModelsProjectLock(value []models.ProjectLock) []models.ProjectLock {
pegomock.RegisterMatcher(&pegomock.EqMatcher{Value: value})
var nullValue []models.ProjectLock
return nullValue
}

View File

@@ -0,0 +1,20 @@
package matchers
import (
"reflect"
events "github.com/hootsuite/atlantis/server/events"
"github.com/petergtz/pegomock"
)
func AnyEventsCommandResponse() events.CommandResponse {
pegomock.RegisterMatcher(pegomock.NewAnyMatcher(reflect.TypeOf((*(events.CommandResponse))(nil)).Elem()))
var nullValue events.CommandResponse
return nullValue
}
func EqEventsCommandResponse(value events.CommandResponse) events.CommandResponse {
pegomock.RegisterMatcher(&pegomock.EqMatcher{Value: value})
var nullValue events.CommandResponse
return nullValue
}

View File

@@ -0,0 +1,20 @@
package matchers
import (
"reflect"
events "github.com/hootsuite/atlantis/server/events"
"github.com/petergtz/pegomock"
)
func AnyEventsPreExecuteResult() events.PreExecuteResult {
pegomock.RegisterMatcher(pegomock.NewAnyMatcher(reflect.TypeOf((*(events.PreExecuteResult))(nil)).Elem()))
var nullValue events.PreExecuteResult
return nullValue
}
func EqEventsPreExecuteResult(value events.PreExecuteResult) events.PreExecuteResult {
pegomock.RegisterMatcher(&pegomock.EqMatcher{Value: value})
var nullValue events.PreExecuteResult
return nullValue
}

View File

@@ -0,0 +1,20 @@
package matchers
import (
"reflect"
events "github.com/hootsuite/atlantis/server/events"
"github.com/petergtz/pegomock"
)
func AnyEventsProjectConfig() events.ProjectConfig {
pegomock.RegisterMatcher(pegomock.NewAnyMatcher(reflect.TypeOf((*(events.ProjectConfig))(nil)).Elem()))
var nullValue events.ProjectConfig
return nullValue
}
func EqEventsProjectConfig(value events.ProjectConfig) events.ProjectConfig {
pegomock.RegisterMatcher(&pegomock.EqMatcher{Value: value})
var nullValue events.ProjectConfig
return nullValue
}

View File

@@ -0,0 +1,20 @@
package matchers
import (
"reflect"
go_gitlab "github.com/lkysow/go-gitlab"
"github.com/petergtz/pegomock"
)
func AnyGoGitlabMergeCommentEvent() go_gitlab.MergeCommentEvent {
pegomock.RegisterMatcher(pegomock.NewAnyMatcher(reflect.TypeOf((*(go_gitlab.MergeCommentEvent))(nil)).Elem()))
var nullValue go_gitlab.MergeCommentEvent
return nullValue
}
func EqGoGitlabMergeCommentEvent(value go_gitlab.MergeCommentEvent) go_gitlab.MergeCommentEvent {
pegomock.RegisterMatcher(&pegomock.EqMatcher{Value: value})
var nullValue go_gitlab.MergeCommentEvent
return nullValue
}

View File

@@ -0,0 +1,20 @@
package matchers
import (
"reflect"
go_gitlab "github.com/lkysow/go-gitlab"
"github.com/petergtz/pegomock"
)
func AnyGoGitlabMergeEvent() go_gitlab.MergeEvent {
pegomock.RegisterMatcher(pegomock.NewAnyMatcher(reflect.TypeOf((*(go_gitlab.MergeEvent))(nil)).Elem()))
var nullValue go_gitlab.MergeEvent
return nullValue
}
func EqGoGitlabMergeEvent(value go_gitlab.MergeEvent) go_gitlab.MergeEvent {
pegomock.RegisterMatcher(&pegomock.EqMatcher{Value: value})
var nullValue go_gitlab.MergeEvent
return nullValue
}

View File

@@ -0,0 +1,20 @@
package matchers
import (
"reflect"
models "github.com/hootsuite/atlantis/server/events/models"
"github.com/petergtz/pegomock"
)
func AnyModelsProject() models.Project {
pegomock.RegisterMatcher(pegomock.NewAnyMatcher(reflect.TypeOf((*(models.Project))(nil)).Elem()))
var nullValue models.Project
return nullValue
}
func EqModelsProject(value models.Project) models.Project {
pegomock.RegisterMatcher(&pegomock.EqMatcher{Value: value})
var nullValue models.Project
return nullValue
}

View File

@@ -0,0 +1,20 @@
package matchers
import (
"reflect"
models "github.com/hootsuite/atlantis/server/events/models"
"github.com/petergtz/pegomock"
)
func AnyModelsPullRequest() models.PullRequest {
pegomock.RegisterMatcher(pegomock.NewAnyMatcher(reflect.TypeOf((*(models.PullRequest))(nil)).Elem()))
var nullValue models.PullRequest
return nullValue
}
func EqModelsPullRequest(value models.PullRequest) models.PullRequest {
pegomock.RegisterMatcher(&pegomock.EqMatcher{Value: value})
var nullValue models.PullRequest
return nullValue
}

View File

@@ -0,0 +1,20 @@
package matchers
import (
"reflect"
models "github.com/hootsuite/atlantis/server/events/models"
"github.com/petergtz/pegomock"
)
func AnyModelsRepo() models.Repo {
pegomock.RegisterMatcher(pegomock.NewAnyMatcher(reflect.TypeOf((*(models.Repo))(nil)).Elem()))
var nullValue models.Repo
return nullValue
}
func EqModelsRepo(value models.Repo) models.Repo {
pegomock.RegisterMatcher(&pegomock.EqMatcher{Value: value})
var nullValue models.Repo
return nullValue
}

View File

@@ -0,0 +1,20 @@
package matchers
import (
"reflect"
models "github.com/hootsuite/atlantis/server/events/models"
"github.com/petergtz/pegomock"
)
func AnyModelsUser() models.User {
pegomock.RegisterMatcher(pegomock.NewAnyMatcher(reflect.TypeOf((*(models.User))(nil)).Elem()))
var nullValue models.User
return nullValue
}
func EqModelsUser(value models.User) models.User {
pegomock.RegisterMatcher(&pegomock.EqMatcher{Value: value})
var nullValue models.User
return nullValue
}

View File

@@ -0,0 +1,20 @@
package matchers
import (
"reflect"
events "github.com/hootsuite/atlantis/server/events"
"github.com/petergtz/pegomock"
)
func AnyPtrToEventsCommand() *events.Command {
pegomock.RegisterMatcher(pegomock.NewAnyMatcher(reflect.TypeOf((*(*events.Command))(nil)).Elem()))
var nullValue *events.Command
return nullValue
}
func EqPtrToEventsCommand(value *events.Command) *events.Command {
pegomock.RegisterMatcher(&pegomock.EqMatcher{Value: value})
var nullValue *events.Command
return nullValue
}

View File

@@ -0,0 +1,20 @@
package matchers
import (
"reflect"
events "github.com/hootsuite/atlantis/server/events"
"github.com/petergtz/pegomock"
)
func AnyPtrToEventsCommandContext() *events.CommandContext {
pegomock.RegisterMatcher(pegomock.NewAnyMatcher(reflect.TypeOf((*(*events.CommandContext))(nil)).Elem()))
var nullValue *events.CommandContext
return nullValue
}
func EqPtrToEventsCommandContext(value *events.CommandContext) *events.CommandContext {
pegomock.RegisterMatcher(&pegomock.EqMatcher{Value: value})
var nullValue *events.CommandContext
return nullValue
}

View File

@@ -0,0 +1,20 @@
package matchers
import (
"reflect"
github "github.com/google/go-github/github"
"github.com/petergtz/pegomock"
)
func AnyPtrToGithubIssueCommentEvent() *github.IssueCommentEvent {
pegomock.RegisterMatcher(pegomock.NewAnyMatcher(reflect.TypeOf((*(*github.IssueCommentEvent))(nil)).Elem()))
var nullValue *github.IssueCommentEvent
return nullValue
}
func EqPtrToGithubIssueCommentEvent(value *github.IssueCommentEvent) *github.IssueCommentEvent {
pegomock.RegisterMatcher(&pegomock.EqMatcher{Value: value})
var nullValue *github.IssueCommentEvent
return nullValue
}

View File

@@ -0,0 +1,20 @@
package matchers
import (
"reflect"
github "github.com/google/go-github/github"
"github.com/petergtz/pegomock"
)
func AnyPtrToGithubPullRequest() *github.PullRequest {
pegomock.RegisterMatcher(pegomock.NewAnyMatcher(reflect.TypeOf((*(*github.PullRequest))(nil)).Elem()))
var nullValue *github.PullRequest
return nullValue
}
func EqPtrToGithubPullRequest(value *github.PullRequest) *github.PullRequest {
pegomock.RegisterMatcher(&pegomock.EqMatcher{Value: value})
var nullValue *github.PullRequest
return nullValue
}

View File

@@ -0,0 +1,20 @@
package matchers
import (
"reflect"
github "github.com/google/go-github/github"
"github.com/petergtz/pegomock"
)
func AnyPtrToGithubRepository() *github.Repository {
pegomock.RegisterMatcher(pegomock.NewAnyMatcher(reflect.TypeOf((*(*github.Repository))(nil)).Elem()))
var nullValue *github.Repository
return nullValue
}
func EqPtrToGithubRepository(value *github.Repository) *github.Repository {
pegomock.RegisterMatcher(&pegomock.EqMatcher{Value: value})
var nullValue *github.Repository
return nullValue
}

View File

@@ -0,0 +1,20 @@
package matchers
import (
"reflect"
go_gitlab "github.com/lkysow/go-gitlab"
"github.com/petergtz/pegomock"
)
func AnyPtrToGoGitlabMergeRequest() *go_gitlab.MergeRequest {
pegomock.RegisterMatcher(pegomock.NewAnyMatcher(reflect.TypeOf((*(*go_gitlab.MergeRequest))(nil)).Elem()))
var nullValue *go_gitlab.MergeRequest
return nullValue
}
func EqPtrToGoGitlabMergeRequest(value *go_gitlab.MergeRequest) *go_gitlab.MergeRequest {
pegomock.RegisterMatcher(&pegomock.EqMatcher{Value: value})
var nullValue *go_gitlab.MergeRequest
return nullValue
}

View File

@@ -0,0 +1,20 @@
package matchers
import (
"reflect"
logging "github.com/hootsuite/atlantis/server/logging"
"github.com/petergtz/pegomock"
)
func AnyPtrToLoggingSimpleLogger() *logging.SimpleLogger {
pegomock.RegisterMatcher(pegomock.NewAnyMatcher(reflect.TypeOf((*(*logging.SimpleLogger))(nil)).Elem()))
var nullValue *logging.SimpleLogger
return nullValue
}
func EqPtrToLoggingSimpleLogger(value *logging.SimpleLogger) *logging.SimpleLogger {
pegomock.RegisterMatcher(&pegomock.EqMatcher{Value: value})
var nullValue *logging.SimpleLogger
return nullValue
}

View File

@@ -0,0 +1,20 @@
package matchers
import (
"reflect"
models "github.com/hootsuite/atlantis/server/events/models"
"github.com/petergtz/pegomock"
)
func AnySliceOfModelsProject() []models.Project {
pegomock.RegisterMatcher(pegomock.NewAnyMatcher(reflect.TypeOf((*([]models.Project))(nil)).Elem()))
var nullValue []models.Project
return nullValue
}
func EqSliceOfModelsProject(value []models.Project) []models.Project {
pegomock.RegisterMatcher(&pegomock.EqMatcher{Value: value})
var nullValue []models.Project
return nullValue
}

View File

@@ -0,0 +1,19 @@
package matchers
import (
"reflect"
"github.com/petergtz/pegomock"
)
func AnySliceOfString() []string {
pegomock.RegisterMatcher(pegomock.NewAnyMatcher(reflect.TypeOf((*([]string))(nil)).Elem()))
var nullValue []string
return nullValue
}
func EqSliceOfString(value []string) []string {
pegomock.RegisterMatcher(&pegomock.EqMatcher{Value: value})
var nullValue []string
return nullValue
}

View File

@@ -0,0 +1,20 @@
package matchers
import (
"reflect"
vcs "github.com/hootsuite/atlantis/server/events/vcs"
"github.com/petergtz/pegomock"
)
func AnyVcsCommitStatus() vcs.CommitStatus {
pegomock.RegisterMatcher(pegomock.NewAnyMatcher(reflect.TypeOf((*(vcs.CommitStatus))(nil)).Elem()))
var nullValue vcs.CommitStatus
return nullValue
}
func EqVcsCommitStatus(value vcs.CommitStatus) vcs.CommitStatus {
pegomock.RegisterMatcher(&pegomock.EqMatcher{Value: value})
var nullValue vcs.CommitStatus
return nullValue
}

View File

@@ -0,0 +1,20 @@
package matchers
import (
"reflect"
vcs "github.com/hootsuite/atlantis/server/events/vcs"
"github.com/petergtz/pegomock"
)
func AnyVcsHost() vcs.Host {
pegomock.RegisterMatcher(pegomock.NewAnyMatcher(reflect.TypeOf((*(vcs.Host))(nil)).Elem()))
var nullValue vcs.Host
return nullValue
}
func EqVcsHost(value vcs.Host) vcs.Host {
pegomock.RegisterMatcher(&pegomock.EqMatcher{Value: value})
var nullValue vcs.Host
return nullValue
}

View File

@@ -13,7 +13,7 @@ import (
"github.com/pkg/errors"
)
//go:generate pegomock generate --use-experimental-model-gen --package mocks -o mocks/mock_lock_url_generator.go LockURLGenerator
//go:generate pegomock generate -m --use-experimental-model-gen --package mocks -o mocks/mock_lock_url_generator.go LockURLGenerator
type LockURLGenerator interface {
// SetLockURL takes a function that given a lock id, will return a url

View File

@@ -12,6 +12,7 @@ import (
rmocks "github.com/hootsuite/atlantis/server/events/run/mocks"
tmocks "github.com/hootsuite/atlantis/server/events/terraform/mocks"
vcsmocks "github.com/hootsuite/atlantis/server/events/vcs/mocks"
"github.com/hootsuite/atlantis/server/events/vcs/mocks/matchers"
"github.com/hootsuite/atlantis/server/logging"
. "github.com/hootsuite/atlantis/testing"
. "github.com/petergtz/pegomock"
@@ -34,7 +35,7 @@ var planCtx = events.CommandContext{
func TestExecute_ModifiedFilesErr(t *testing.T) {
t.Log("If GetModifiedFiles returns an error we return an error")
p, _, _ := setupPlanExecutorTest(t)
When(p.VCSClient.GetModifiedFiles(AnyRepo(), AnyPullRequest(), AnyVCSHost())).ThenReturn(nil, errors.New("err"))
When(p.VCSClient.GetModifiedFiles(matchers.AnyModelsRepo(), matchers.AnyModelsPullRequest(), matchers.AnyVcsHost())).ThenReturn(nil, errors.New("err"))
r := p.Execute(&planCtx)
Assert(t, r.Error != nil, "exp .Error to be set")
@@ -54,7 +55,7 @@ func TestExecute_NoModifiedProjects(t *testing.T) {
func TestExecute_CloneErr(t *testing.T) {
t.Log("If Workspace.Clone returns an error we return an error")
p, _, _ := setupPlanExecutorTest(t)
When(p.VCSClient.GetModifiedFiles(AnyRepo(), AnyPullRequest(), AnyVCSHost())).ThenReturn([]string{"file.tf"}, nil)
When(p.VCSClient.GetModifiedFiles(matchers.AnyModelsRepo(), matchers.AnyModelsPullRequest(), matchers.AnyVcsHost())).ThenReturn([]string{"file.tf"}, nil)
When(p.Workspace.Clone(planCtx.Log, planCtx.BaseRepo, planCtx.HeadRepo, planCtx.Pull, "env")).ThenReturn("", errors.New("err"))
r := p.Execute(&planCtx)
@@ -65,7 +66,7 @@ func TestExecute_CloneErr(t *testing.T) {
func TestExecute_Success(t *testing.T) {
t.Log("If there are no errors, the plan should be returned")
p, runner, _ := setupPlanExecutorTest(t)
When(p.VCSClient.GetModifiedFiles(AnyRepo(), AnyPullRequest(), AnyVCSHost())).ThenReturn([]string{"file.tf"}, nil)
When(p.VCSClient.GetModifiedFiles(matchers.AnyModelsRepo(), matchers.AnyModelsPullRequest(), matchers.AnyVcsHost())).ThenReturn([]string{"file.tf"}, nil)
When(p.Workspace.Clone(planCtx.Log, planCtx.BaseRepo, planCtx.HeadRepo, planCtx.Pull, "env")).
ThenReturn("/tmp/clone-repo", nil)
When(p.ProjectPreExecute.Execute(&planCtx, "/tmp/clone-repo", models.Project{RepoFullName: "", Path: "."})).
@@ -94,7 +95,7 @@ func TestExecute_Success(t *testing.T) {
func TestExecute_PreExecuteResult(t *testing.T) {
t.Log("If ProjectPreExecute.Execute returns a ProjectResult we should return it")
p, _, _ := setupPlanExecutorTest(t)
When(p.VCSClient.GetModifiedFiles(AnyRepo(), AnyPullRequest(), AnyVCSHost())).ThenReturn([]string{"file.tf"}, nil)
When(p.VCSClient.GetModifiedFiles(matchers.AnyModelsRepo(), matchers.AnyModelsPullRequest(), matchers.AnyVcsHost())).ThenReturn([]string{"file.tf"}, nil)
When(p.Workspace.Clone(planCtx.Log, planCtx.BaseRepo, planCtx.HeadRepo, planCtx.Pull, "env")).
ThenReturn("/tmp/clone-repo", nil)
projectResult := events.ProjectResult{
@@ -113,7 +114,7 @@ func TestExecute_MultiProjectFailure(t *testing.T) {
t.Log("If is an error planning in one project it should be returned. It shouldn't affect another project though.")
p, runner, locker := setupPlanExecutorTest(t)
// Two projects have been modified so we should run plan in two paths.
When(p.VCSClient.GetModifiedFiles(AnyRepo(), AnyPullRequest(), AnyVCSHost())).ThenReturn([]string{"path1/file.tf", "path2/file.tf"}, nil)
When(p.VCSClient.GetModifiedFiles(matchers.AnyModelsRepo(), matchers.AnyModelsPullRequest(), matchers.AnyVcsHost())).ThenReturn([]string{"path1/file.tf", "path2/file.tf"}, nil)
When(p.Workspace.Clone(planCtx.Log, planCtx.BaseRepo, planCtx.HeadRepo, planCtx.Pull, "env")).
ThenReturn("/tmp/clone-repo", nil)
@@ -153,7 +154,7 @@ func TestExecute_MultiProjectFailure(t *testing.T) {
func TestExecute_PostPlanCommands(t *testing.T) {
t.Log("Should execute post-plan commands and return if there is an error")
p, _, _ := setupPlanExecutorTest(t)
When(p.VCSClient.GetModifiedFiles(AnyRepo(), AnyPullRequest(), AnyVCSHost())).ThenReturn([]string{"file.tf"}, nil)
When(p.VCSClient.GetModifiedFiles(matchers.AnyModelsRepo(), matchers.AnyModelsPullRequest(), matchers.AnyVcsHost())).ThenReturn([]string{"file.tf"}, nil)
When(p.Workspace.Clone(planCtx.Log, planCtx.BaseRepo, planCtx.HeadRepo, planCtx.Pull, "env")).
ThenReturn("/tmp/clone-repo", nil)
When(p.ProjectPreExecute.Execute(&planCtx, "/tmp/clone-repo", models.Project{RepoFullName: "", Path: "."})).

View File

@@ -12,7 +12,7 @@ import (
const ProjectConfigFile = "atlantis.yaml"
//go:generate pegomock generate --use-experimental-model-gen --package mocks -o mocks/mock_project_config_reader.go ProjectConfigReader
//go:generate pegomock generate -m --use-experimental-model-gen --package mocks -o mocks/mock_project_config_reader.go ProjectConfigReader
// ProjectConfigReader implements reading project config.
type ProjectConfigReader interface {

View File

@@ -8,7 +8,7 @@ import (
"github.com/hootsuite/atlantis/server/logging"
)
//go:generate pegomock generate --use-experimental-model-gen --package mocks -o mocks/mock_modified_project_finder.go ModifiedProjectFinder
//go:generate pegomock generate -m --use-experimental-model-gen --package mocks -o mocks/mock_modified_project_finder.go ModifiedProjectFinder
type ModifiedProjectFinder interface {
// FindModified returns the list of projects that were modified based on

View File

@@ -13,7 +13,7 @@ import (
"github.com/pkg/errors"
)
//go:generate pegomock generate --use-experimental-model-gen --package mocks -o mocks/mock_project_pre_executor.go ProjectPreExecutor
//go:generate pegomock generate -m --use-experimental-model-gen --package mocks -o mocks/mock_project_pre_executor.go ProjectPreExecutor
type ProjectPreExecutor interface {
Execute(ctx *CommandContext, repoDir string, project models.Project) PreExecuteResult

View File

@@ -14,7 +14,7 @@ import (
"github.com/pkg/errors"
)
//go:generate pegomock generate --use-experimental-model-gen --package mocks -o mocks/mock_pull_cleaner.go PullCleaner
//go:generate pegomock generate -m --use-experimental-model-gen --package mocks -o mocks/mock_pull_cleaner.go PullCleaner
type PullCleaner interface {
CleanUpPull(repo models.Repo, pull models.PullRequest, host vcs.Host) error

View File

@@ -2,12 +2,12 @@ package events_test
import (
"errors"
"reflect"
"testing"
"github.com/hootsuite/atlantis/server/events"
lockmocks "github.com/hootsuite/atlantis/server/events/locking/mocks"
"github.com/hootsuite/atlantis/server/events/mocks"
"github.com/hootsuite/atlantis/server/events/mocks/matchers"
"github.com/hootsuite/atlantis/server/events/models"
"github.com/hootsuite/atlantis/server/events/models/fixtures"
"github.com/hootsuite/atlantis/server/events/vcs"
@@ -58,7 +58,7 @@ func TestCleanUpPullNoLocks(t *testing.T) {
When(l.UnlockByPull(fixtures.Repo.FullName, fixtures.Pull.Num)).ThenReturn(nil, nil)
err := pce.CleanUpPull(fixtures.Repo, fixtures.Pull, vcs.Github)
Ok(t, err)
cp.VerifyWasCalled(Never()).CreateComment(AnyRepo(), AnyPullRequest(), AnyString(), AnyVCSHost())
cp.VerifyWasCalled(Never()).CreateComment(matchers.AnyModelsRepo(), matchers.AnyModelsPullRequest(), AnyString(), matchers.AnyVcsHost())
}
func TestCleanUpPullComments(t *testing.T) {
@@ -139,19 +139,9 @@ func TestCleanUpPullComments(t *testing.T) {
When(l.UnlockByPull(fixtures.Repo.FullName, fixtures.Pull.Num)).ThenReturn(c.Locks, nil)
err := pce.CleanUpPull(fixtures.Repo, fixtures.Pull, vcs.Github)
Ok(t, err)
_, _, comment, _ := cp.VerifyWasCalledOnce().CreateComment(AnyRepo(), AnyPullRequest(), AnyString(), AnyVCSHost()).GetCapturedArguments()
_, _, comment, _ := cp.VerifyWasCalledOnce().CreateComment(matchers.AnyModelsRepo(), matchers.AnyModelsPullRequest(), AnyString(), matchers.AnyVcsHost()).GetCapturedArguments()
expected := "Locks and plans deleted for the projects and environments modified in this pull request:\n\n" + c.Exp
Equals(t, expected, comment)
}
}
func AnyRepo() models.Repo {
RegisterMatcher(NewAnyMatcher(reflect.TypeOf(models.Repo{})))
return models.Repo{}
}
func AnyPullRequest() models.PullRequest {
RegisterMatcher(NewAnyMatcher(reflect.TypeOf(models.PullRequest{})))
return models.PullRequest{}
}

View File

@@ -0,0 +1,20 @@
package matchers
import (
"reflect"
go_version "github.com/hashicorp/go-version"
"github.com/petergtz/pegomock"
)
func AnyPtrToGoVersionVersion() *go_version.Version {
pegomock.RegisterMatcher(pegomock.NewAnyMatcher(reflect.TypeOf((*(*go_version.Version))(nil)).Elem()))
var nullValue *go_version.Version
return nullValue
}
func EqPtrToGoVersionVersion(value *go_version.Version) *go_version.Version {
pegomock.RegisterMatcher(&pegomock.EqMatcher{Value: value})
var nullValue *go_version.Version
return nullValue
}

View File

@@ -0,0 +1,20 @@
package matchers
import (
"reflect"
logging "github.com/hootsuite/atlantis/server/logging"
"github.com/petergtz/pegomock"
)
func AnyPtrToLoggingSimpleLogger() *logging.SimpleLogger {
pegomock.RegisterMatcher(pegomock.NewAnyMatcher(reflect.TypeOf((*(*logging.SimpleLogger))(nil)).Elem()))
var nullValue *logging.SimpleLogger
return nullValue
}
func EqPtrToLoggingSimpleLogger(value *logging.SimpleLogger) *logging.SimpleLogger {
pegomock.RegisterMatcher(&pegomock.EqMatcher{Value: value})
var nullValue *logging.SimpleLogger
return nullValue
}

View File

@@ -0,0 +1,19 @@
package matchers
import (
"reflect"
"github.com/petergtz/pegomock"
)
func AnySliceOfString() []string {
pegomock.RegisterMatcher(pegomock.NewAnyMatcher(reflect.TypeOf((*([]string))(nil)).Elem()))
var nullValue []string
return nullValue
}
func EqSliceOfString(value []string) []string {
pegomock.RegisterMatcher(&pegomock.EqMatcher{Value: value})
var nullValue []string
return nullValue
}

View File

@@ -17,7 +17,7 @@ import (
const inlineShebang = "#!/bin/sh -e"
//go:generate pegomock generate --use-experimental-model-gen --package mocks -o mocks/mock_runner.go Runner
//go:generate pegomock generate -m --use-experimental-model-gen --package mocks -o mocks/mock_runner.go Runner
type Runner interface {
Execute(log *logging.SimpleLogger, commands []string, path string, environment string, terraformVersion *version.Version, stage string) (string, error)

View File

@@ -0,0 +1,20 @@
package matchers
import (
"reflect"
go_version "github.com/hashicorp/go-version"
"github.com/petergtz/pegomock"
)
func AnyPtrToGoVersionVersion() *go_version.Version {
pegomock.RegisterMatcher(pegomock.NewAnyMatcher(reflect.TypeOf((*(*go_version.Version))(nil)).Elem()))
var nullValue *go_version.Version
return nullValue
}
func EqPtrToGoVersionVersion(value *go_version.Version) *go_version.Version {
pegomock.RegisterMatcher(&pegomock.EqMatcher{Value: value})
var nullValue *go_version.Version
return nullValue
}

View File

@@ -0,0 +1,20 @@
package matchers
import (
"reflect"
logging "github.com/hootsuite/atlantis/server/logging"
"github.com/petergtz/pegomock"
)
func AnyPtrToLoggingSimpleLogger() *logging.SimpleLogger {
pegomock.RegisterMatcher(pegomock.NewAnyMatcher(reflect.TypeOf((*(*logging.SimpleLogger))(nil)).Elem()))
var nullValue *logging.SimpleLogger
return nullValue
}
func EqPtrToLoggingSimpleLogger(value *logging.SimpleLogger) *logging.SimpleLogger {
pegomock.RegisterMatcher(&pegomock.EqMatcher{Value: value})
var nullValue *logging.SimpleLogger
return nullValue
}

View File

@@ -0,0 +1,19 @@
package matchers
import (
"reflect"
"github.com/petergtz/pegomock"
)
func AnySliceOfString() []string {
pegomock.RegisterMatcher(pegomock.NewAnyMatcher(reflect.TypeOf((*([]string))(nil)).Elem()))
var nullValue []string
return nullValue
}
func EqSliceOfString(value []string) []string {
pegomock.RegisterMatcher(&pegomock.EqMatcher{Value: value})
var nullValue []string
return nullValue
}

View File

@@ -14,7 +14,7 @@ import (
"github.com/pkg/errors"
)
//go:generate pegomock generate --use-experimental-model-gen --package mocks -o mocks/mock_runner.go Runner
//go:generate pegomock generate -m --use-experimental-model-gen --package mocks -o mocks/mock_runner.go Runner
type Runner interface {
Version() *version.Version

View File

@@ -4,7 +4,7 @@ import (
"github.com/hootsuite/atlantis/server/events/models"
)
//go:generate pegomock generate --use-experimental-model-gen --package mocks -o mocks/mock_client.go Client
//go:generate pegomock generate -m --use-experimental-model-gen --package mocks -o mocks/mock_client.go Client
// Client is used to make API calls to a VCS host like GitHub or GitLab.
type Client interface {

View File

@@ -0,0 +1,20 @@
package matchers
import (
"reflect"
models "github.com/hootsuite/atlantis/server/events/models"
"github.com/petergtz/pegomock"
)
func AnyModelsPullRequest() models.PullRequest {
pegomock.RegisterMatcher(pegomock.NewAnyMatcher(reflect.TypeOf((*(models.PullRequest))(nil)).Elem()))
var nullValue models.PullRequest
return nullValue
}
func EqModelsPullRequest(value models.PullRequest) models.PullRequest {
pegomock.RegisterMatcher(&pegomock.EqMatcher{Value: value})
var nullValue models.PullRequest
return nullValue
}

View File

@@ -0,0 +1,20 @@
package matchers
import (
"reflect"
models "github.com/hootsuite/atlantis/server/events/models"
"github.com/petergtz/pegomock"
)
func AnyModelsRepo() models.Repo {
pegomock.RegisterMatcher(pegomock.NewAnyMatcher(reflect.TypeOf((*(models.Repo))(nil)).Elem()))
var nullValue models.Repo
return nullValue
}
func EqModelsRepo(value models.Repo) models.Repo {
pegomock.RegisterMatcher(&pegomock.EqMatcher{Value: value})
var nullValue models.Repo
return nullValue
}

View File

@@ -0,0 +1,19 @@
package matchers
import (
"reflect"
"github.com/petergtz/pegomock"
)
func AnySliceOfString() []string {
pegomock.RegisterMatcher(pegomock.NewAnyMatcher(reflect.TypeOf((*([]string))(nil)).Elem()))
var nullValue []string
return nullValue
}
func EqSliceOfString(value []string) []string {
pegomock.RegisterMatcher(&pegomock.EqMatcher{Value: value})
var nullValue []string
return nullValue
}

View File

@@ -0,0 +1,20 @@
package matchers
import (
"reflect"
vcs "github.com/hootsuite/atlantis/server/events/vcs"
"github.com/petergtz/pegomock"
)
func AnyVcsCommitStatus() vcs.CommitStatus {
pegomock.RegisterMatcher(pegomock.NewAnyMatcher(reflect.TypeOf((*(vcs.CommitStatus))(nil)).Elem()))
var nullValue vcs.CommitStatus
return nullValue
}
func EqVcsCommitStatus(value vcs.CommitStatus) vcs.CommitStatus {
pegomock.RegisterMatcher(&pegomock.EqMatcher{Value: value})
var nullValue vcs.CommitStatus
return nullValue
}

View File

@@ -0,0 +1,20 @@
package matchers
import (
"reflect"
vcs "github.com/hootsuite/atlantis/server/events/vcs"
"github.com/petergtz/pegomock"
)
func AnyVcsHost() vcs.Host {
pegomock.RegisterMatcher(pegomock.NewAnyMatcher(reflect.TypeOf((*(vcs.Host))(nil)).Elem()))
var nullValue vcs.Host
return nullValue
}
func EqVcsHost(value vcs.Host) vcs.Host {
pegomock.RegisterMatcher(&pegomock.EqMatcher{Value: value})
var nullValue vcs.Host
return nullValue
}

View File

@@ -5,7 +5,7 @@ import (
"github.com/pkg/errors"
)
//go:generate pegomock generate --use-experimental-model-gen --package mocks -o mocks/mock_proxy.go ClientProxy
//go:generate pegomock generate -m --use-experimental-model-gen --package mocks -o mocks/mock_proxy.go ClientProxy
// ClientProxy proxies calls to the correct VCS client depending on which
// VCS host is required.

View File

@@ -0,0 +1,20 @@
package matchers
import (
"reflect"
logging "github.com/hootsuite/atlantis/server/logging"
"github.com/petergtz/pegomock"
)
func AnyPtrToLoggingSimpleLogger() *logging.SimpleLogger {
pegomock.RegisterMatcher(pegomock.NewAnyMatcher(reflect.TypeOf((*(*logging.SimpleLogger))(nil)).Elem()))
var nullValue *logging.SimpleLogger
return nullValue
}
func EqPtrToLoggingSimpleLogger(value *logging.SimpleLogger) *logging.SimpleLogger {
pegomock.RegisterMatcher(&pegomock.EqMatcher{Value: value})
var nullValue *logging.SimpleLogger
return nullValue
}

View File

@@ -0,0 +1,20 @@
package matchers
import (
"reflect"
slack "github.com/nlopes/slack"
"github.com/petergtz/pegomock"
)
func AnyPtrToSlackAuthTestResponse() *slack.AuthTestResponse {
pegomock.RegisterMatcher(pegomock.NewAnyMatcher(reflect.TypeOf((*(*slack.AuthTestResponse))(nil)).Elem()))
var nullValue *slack.AuthTestResponse
return nullValue
}
func EqPtrToSlackAuthTestResponse(value *slack.AuthTestResponse) *slack.AuthTestResponse {
pegomock.RegisterMatcher(&pegomock.EqMatcher{Value: value})
var nullValue *slack.AuthTestResponse
return nullValue
}

View File

@@ -0,0 +1,20 @@
package matchers
import (
"reflect"
slack "github.com/nlopes/slack"
"github.com/petergtz/pegomock"
)
func AnySlackPostMessageParameters() slack.PostMessageParameters {
pegomock.RegisterMatcher(pegomock.NewAnyMatcher(reflect.TypeOf((*(slack.PostMessageParameters))(nil)).Elem()))
var nullValue slack.PostMessageParameters
return nullValue
}
func EqSlackPostMessageParameters(value slack.PostMessageParameters) slack.PostMessageParameters {
pegomock.RegisterMatcher(&pegomock.EqMatcher{Value: value})
var nullValue slack.PostMessageParameters
return nullValue
}

View File

@@ -0,0 +1,20 @@
package matchers
import (
"reflect"
slack "github.com/nlopes/slack"
"github.com/petergtz/pegomock"
)
func AnySliceOfSlackChannel() []slack.Channel {
pegomock.RegisterMatcher(pegomock.NewAnyMatcher(reflect.TypeOf((*([]slack.Channel))(nil)).Elem()))
var nullValue []slack.Channel
return nullValue
}
func EqSliceOfSlackChannel(value []slack.Channel) []slack.Channel {
pegomock.RegisterMatcher(&pegomock.EqMatcher{Value: value})
var nullValue []slack.Channel
return nullValue
}

View File

@@ -0,0 +1,20 @@
package matchers
import (
"reflect"
webhooks "github.com/hootsuite/atlantis/server/events/webhooks"
"github.com/petergtz/pegomock"
)
func AnyWebhooksApplyResult() webhooks.ApplyResult {
pegomock.RegisterMatcher(pegomock.NewAnyMatcher(reflect.TypeOf((*(webhooks.ApplyResult))(nil)).Elem()))
var nullValue webhooks.ApplyResult
return nullValue
}
func EqWebhooksApplyResult(value webhooks.ApplyResult) webhooks.ApplyResult {
pegomock.RegisterMatcher(&pegomock.EqMatcher{Value: value})
var nullValue webhooks.ApplyResult
return nullValue
}

View File

@@ -11,7 +11,7 @@ const (
slackFailureColour = "danger"
)
//go:generate pegomock generate --use-experimental-model-gen --package mocks -o mocks/mock_slack_client.go SlackClient
//go:generate pegomock generate -m --use-experimental-model-gen --package mocks -o mocks/mock_slack_client.go SlackClient
// SlackClient handles making API calls to Slack.
type SlackClient interface {
@@ -21,7 +21,7 @@ type SlackClient interface {
PostMessage(channel string, applyResult ApplyResult) error
}
//go:generate pegomock generate --use-experimental-model-gen --package mocks -o mocks/mock_underlying_slack_client.go UnderlyingSlackClient
//go:generate pegomock generate -m --use-experimental-model-gen --package mocks -o mocks/mock_underlying_slack_client.go UnderlyingSlackClient
// UnderlyingSlackClient wraps the nlopes/slack.Client implementation so
// we can mock it during tests.

View File

@@ -13,7 +13,7 @@ import (
const SlackKind = "slack"
const ApplyEvent = "apply"
//go:generate pegomock generate --use-experimental-model-gen --package mocks -o mocks/mock_sender.go Sender
//go:generate pegomock generate -m --use-experimental-model-gen --package mocks -o mocks/mock_sender.go Sender
// Sender sends webhooks.
type Sender interface {

View File

@@ -14,7 +14,7 @@ import (
const workspacePrefix = "repos"
//go:generate pegomock generate --use-experimental-model-gen --package mocks -o mocks/mock_workspace.go Workspace
//go:generate pegomock generate -m --use-experimental-model-gen --package mocks -o mocks/mock_workspace.go Workspace
type Workspace interface {
// Clone git clones headRepo, checks out the branch and then returns the absolute

View File

@@ -5,14 +5,13 @@ import (
"errors"
"net/http"
"net/http/httptest"
"reflect"
"testing"
"time"
"github.com/google/go-github/github"
"github.com/hootsuite/atlantis/server"
"github.com/hootsuite/atlantis/server/events"
emocks "github.com/hootsuite/atlantis/server/events/mocks"
"github.com/hootsuite/atlantis/server/events/mocks/matchers"
"github.com/hootsuite/atlantis/server/events/models"
"github.com/hootsuite/atlantis/server/events/vcs"
"github.com/hootsuite/atlantis/server/logging"
@@ -113,7 +112,7 @@ func TestPost_GithubInvalidComment(t *testing.T) {
eventsReq.Header.Set(githubHeader, "issue_comment")
event := `{"action": "created"}`
When(v.Validate(eventsReq, secret)).ThenReturn([]byte(event), nil)
When(p.ParseGithubIssueCommentEvent(AnyComment())).ThenReturn(models.Repo{}, models.User{}, 1, errors.New("err"))
When(p.ParseGithubIssueCommentEvent(matchers.AnyPtrToGithubIssueCommentEvent())).ThenReturn(models.Repo{}, models.User{}, 1, errors.New("err"))
w := httptest.NewRecorder()
e.Post(w, eventsReq)
responseContains(t, w, http.StatusBadRequest, "Failed parsing event")
@@ -136,7 +135,7 @@ func TestPost_GithubCommentInvalidCommand(t *testing.T) {
eventsReq.Header.Set(githubHeader, "issue_comment")
event := `{"action": "created"}`
When(v.Validate(eventsReq, secret)).ThenReturn([]byte(event), nil)
When(p.ParseGithubIssueCommentEvent(AnyComment())).ThenReturn(models.Repo{}, models.User{}, 1, nil)
When(p.ParseGithubIssueCommentEvent(matchers.AnyPtrToGithubIssueCommentEvent())).ThenReturn(models.Repo{}, models.User{}, 1, nil)
When(p.DetermineCommand("", vcs.Github)).ThenReturn(nil, errors.New("err"))
w := httptest.NewRecorder()
e.Post(w, eventsReq)
@@ -166,7 +165,7 @@ func TestPost_GithubCommentSuccess(t *testing.T) {
baseRepo := models.Repo{}
user := models.User{}
cmd := events.Command{}
When(p.ParseGithubIssueCommentEvent(AnyComment())).ThenReturn(baseRepo, user, 1, nil)
When(p.ParseGithubIssueCommentEvent(matchers.AnyPtrToGithubIssueCommentEvent())).ThenReturn(baseRepo, user, 1, nil)
When(p.DetermineCommand("", vcs.Github)).ThenReturn(&cmd, nil)
w := httptest.NewRecorder()
e.Post(w, eventsReq)
@@ -207,7 +206,7 @@ func TestPost_GithubPullRequestInvalid(t *testing.T) {
event := `{"action": "closed"}`
When(v.Validate(eventsReq, secret)).ThenReturn([]byte(event), nil)
When(p.ParseGithubPull(AnyPull())).ThenReturn(models.PullRequest{}, models.Repo{}, errors.New("err"))
When(p.ParseGithubPull(matchers.AnyPtrToGithubPullRequest())).ThenReturn(models.PullRequest{}, models.Repo{}, errors.New("err"))
w := httptest.NewRecorder()
e.Post(w, eventsReq)
responseContains(t, w, http.StatusBadRequest, "Error parsing pull data: err")
@@ -220,8 +219,8 @@ func TestPost_GithubPullRequestInvalidRepo(t *testing.T) {
event := `{"action": "closed"}`
When(v.Validate(eventsReq, secret)).ThenReturn([]byte(event), nil)
When(p.ParseGithubPull(AnyPull())).ThenReturn(models.PullRequest{}, models.Repo{}, nil)
When(p.ParseGithubRepo(AnyRepo())).ThenReturn(models.Repo{}, errors.New("err"))
When(p.ParseGithubPull(matchers.AnyPtrToGithubPullRequest())).ThenReturn(models.PullRequest{}, models.Repo{}, nil)
When(p.ParseGithubRepo(matchers.AnyPtrToGithubRepository())).ThenReturn(models.Repo{}, errors.New("err"))
w := httptest.NewRecorder()
e.Post(w, eventsReq)
responseContains(t, w, http.StatusBadRequest, "Error parsing repo data: err")
@@ -237,8 +236,8 @@ func TestPost_GithubPullRequestErrCleaningPull(t *testing.T) {
When(v.Validate(eventsReq, secret)).ThenReturn([]byte(event), nil)
repo := models.Repo{}
pull := models.PullRequest{}
When(p.ParseGithubPull(AnyPull())).ThenReturn(pull, repo, nil)
When(p.ParseGithubRepo(AnyRepo())).ThenReturn(repo, nil)
When(p.ParseGithubPull(matchers.AnyPtrToGithubPullRequest())).ThenReturn(pull, repo, nil)
When(p.ParseGithubRepo(matchers.AnyPtrToGithubRepository())).ThenReturn(repo, nil)
When(c.CleanUpPull(repo, pull, vcs.Github)).ThenReturn(errors.New("cleanup err"))
w := httptest.NewRecorder()
e.Post(w, eventsReq)
@@ -269,8 +268,8 @@ func TestPost_GithubPullRequestSuccess(t *testing.T) {
When(v.Validate(eventsReq, secret)).ThenReturn([]byte(event), nil)
repo := models.Repo{}
pull := models.PullRequest{}
When(p.ParseGithubPull(AnyPull())).ThenReturn(pull, repo, nil)
When(p.ParseGithubRepo(AnyRepo())).ThenReturn(repo, nil)
When(p.ParseGithubPull(matchers.AnyPtrToGithubPullRequest())).ThenReturn(pull, repo, nil)
When(p.ParseGithubRepo(matchers.AnyPtrToGithubRepository())).ThenReturn(repo, nil)
When(c.CleanUpPull(repo, pull, vcs.Github)).ThenReturn(nil)
w := httptest.NewRecorder()
e.Post(w, eventsReq)
@@ -312,18 +311,3 @@ func setup(t *testing.T) (server.EventsController, *mocks.MockGithubRequestValid
}
return e, v, gl, p, cr, c
}
func AnyComment() *github.IssueCommentEvent {
RegisterMatcher(NewAnyMatcher(reflect.TypeOf(&github.IssueCommentEvent{})))
return &github.IssueCommentEvent{}
}
func AnyPull() *github.PullRequest {
RegisterMatcher(NewAnyMatcher(reflect.TypeOf(&github.PullRequest{})))
return &github.PullRequest{}
}
func AnyRepo() *github.Repository {
RegisterMatcher(NewAnyMatcher(reflect.TypeOf(&github.Repository{})))
return &github.Repository{}
}

View File

@@ -9,7 +9,7 @@ import (
"github.com/google/go-github/github"
)
//go:generate pegomock generate --use-experimental-model-gen --package mocks -o mocks/mock_gh_request_validation.go GithubRequestValidator
//go:generate pegomock generate -m --use-experimental-model-gen --package mocks -o mocks/mock_gh_request_validation.go GithubRequestValidator
// GithubRequestValidator validates GitHub requests.
type GithubRequestValidator interface {

View File

@@ -11,7 +11,7 @@ import (
const secretHeader = "X-Gitlab-Token"
//go:generate pegomock generate --use-experimental-model-gen --package mocks -o mocks/mock_gitlab_request_parser.go GitlabRequestParser
//go:generate pegomock generate -m --use-experimental-model-gen --package mocks -o mocks/mock_gitlab_request_parser.go GitlabRequestParser
// GitlabRequestParser parses and validates GitLab requests.
type GitlabRequestParser interface {

View File

@@ -0,0 +1,20 @@
package matchers
import (
"reflect"
logging "github.com/hootsuite/atlantis/server/logging"
"github.com/petergtz/pegomock"
)
func AnyLoggingLogLevel() logging.LogLevel {
pegomock.RegisterMatcher(pegomock.NewAnyMatcher(reflect.TypeOf((*(logging.LogLevel))(nil)).Elem()))
var nullValue logging.LogLevel
return nullValue
}
func EqLoggingLogLevel(value logging.LogLevel) logging.LogLevel {
pegomock.RegisterMatcher(&pegomock.EqMatcher{Value: value})
var nullValue logging.LogLevel
return nullValue
}

View File

@@ -0,0 +1,20 @@
package matchers
import (
log "log"
"reflect"
"github.com/petergtz/pegomock"
)
func AnyPtrToLogLogger() *log.Logger {
pegomock.RegisterMatcher(pegomock.NewAnyMatcher(reflect.TypeOf((*(*log.Logger))(nil)).Elem()))
var nullValue *log.Logger
return nullValue
}
func EqPtrToLogLogger(value *log.Logger) *log.Logger {
pegomock.RegisterMatcher(&pegomock.EqMatcher{Value: value})
var nullValue *log.Logger
return nullValue
}

View File

@@ -10,7 +10,7 @@ import (
"unicode"
)
//go:generate pegomock generate --use-experimental-model-gen --package mocks -o mocks/mock_simple_logging.go SimpleLogging
//go:generate pegomock generate -m --use-experimental-model-gen --package mocks -o mocks/mock_simple_logging.go SimpleLogging
type SimpleLogging interface {
Debug(format string, a ...interface{})

View File

@@ -0,0 +1,20 @@
package matchers
import (
io "io"
"reflect"
"github.com/petergtz/pegomock"
)
func AnyIoWriter() io.Writer {
pegomock.RegisterMatcher(pegomock.NewAnyMatcher(reflect.TypeOf((*(io.Writer))(nil)).Elem()))
var nullValue io.Writer
return nullValue
}
func EqIoWriter(value io.Writer) io.Writer {
pegomock.RegisterMatcher(&pegomock.EqMatcher{Value: value})
var nullValue io.Writer
return nullValue
}

View File

@@ -0,0 +1,20 @@
package matchers
import (
http "net/http"
"reflect"
"github.com/petergtz/pegomock"
)
func AnyPtrToHttpRequest() *http.Request {
pegomock.RegisterMatcher(pegomock.NewAnyMatcher(reflect.TypeOf((*(*http.Request))(nil)).Elem()))
var nullValue *http.Request
return nullValue
}
func EqPtrToHttpRequest(value *http.Request) *http.Request {
pegomock.RegisterMatcher(&pegomock.EqMatcher{Value: value})
var nullValue *http.Request
return nullValue
}

View File

@@ -0,0 +1,19 @@
package matchers
import (
"reflect"
"github.com/petergtz/pegomock"
)
func AnySliceOfByte() []byte {
pegomock.RegisterMatcher(pegomock.NewAnyMatcher(reflect.TypeOf((*([]byte))(nil)).Elem()))
var nullValue []byte
return nullValue
}
func EqSliceOfByte(value []byte) []byte {
pegomock.RegisterMatcher(&pegomock.EqMatcher{Value: value})
var nullValue []byte
return nullValue
}

View File

@@ -6,7 +6,7 @@ import (
"time"
)
//go:generate pegomock generate --use-experimental-model-gen --package mocks -o mocks/mock_template_writer.go TemplateWriter
//go:generate pegomock generate -m --use-experimental-model-gen --package mocks -o mocks/mock_template_writer.go TemplateWriter
type TemplateWriter interface {
Execute(wr io.Writer, data interface{}) error
}

View File

@@ -1,4 +1,5 @@
mock_display_test.go
matchers
debug.test
.vscode
*.coverprofile

View File

@@ -236,6 +236,9 @@ When(contactList.getContactByFullName(EqString("Dan"), AnyString())).thenReturn(
```
### Writing Your Own Argument Matchers
**Important:** `Eq...` and `Any...` matchers for types used in mock methods, can now be _auto-generated_ while generating the mock. So writing your own argument matchers is not necessary for most use cases. See section [The Pegomock CLI](#generating-mocks) for more information.
You can also write your own matchers for non-basic types. E.g. if you have a `struct MyType`, you can write an _Equals_ and _Any_ matcher like this:
```go
func EqMyType(value MyType) MyType {
@@ -377,6 +380,8 @@ Flags can be any of the following:
- `--package`: Package of the generated code; defaults to the package from which pegomock was executed suffixed with _test
- `--generate-matchers,-m`: This will auto-generate argument matchers and place them in a `matchers` directory alongside the mock source code itself.
For more flags, run:
```
@@ -396,7 +401,7 @@ pegomock generate --use-experimental-model-gen [<flags>] [<packagepath>] <interf
What are the benefits?
- The current default uses the [reflect](https://golang.org/pkg/reflect/) package to introspect the interface for which a mock should be generated. But reflection cannot determine method parameter names, only types. This forces the generator to generate them based on a pattern. In a code editor with code assistence, those pattern-based names (such as `_param0`, `_param1`) are non-descriptive and provide less help while writing code. The new implementation properly parses the source (including *all* dependent packages) and subsequently uses the same names as used in the interface definition.
- With the current default you cannot generate an interface that lives in the `main` package. It's due to the way this implementation works: it imports the interface's package into temporarily generated code that gets compiled on the fly. This compilation fails, because there are now two `main`functions.
- With the current default you cannot generate an interface that lives in the `main` package. It's due to the way this implementation works: it imports the interface's package into temporarily generated code that gets compiled on the fly. This compilation fails, because there are now two `main` functions.
- The new implementation is simpler and will probably become the default in the future, because it will be easier to maintain.
What are the drawbacks?

View File

@@ -99,8 +99,8 @@ func (genericMock *GenericMock) Verify(
if inOrderContext != nil {
for _, methodInvocation := range methodInvocations {
if methodInvocation.orderingInvocationNumber <= inOrderContext.invocationCounter {
GlobalFailHandler(fmt.Sprintf("Expected function call \"%v\" with params %v before function call \"%v\" with params %v",
methodName, params, inOrderContext.lastInvokedMethodName, inOrderContext.lastInvokedMethodParams))
GlobalFailHandler(fmt.Sprintf("Expected function call %v(%v) before function call %v(%v)",
methodName, formatParams(params), inOrderContext.lastInvokedMethodName, formatParams(inOrderContext.lastInvokedMethodParams)))
}
inOrderContext.invocationCounter = methodInvocation.orderingInvocationNumber
inOrderContext.lastInvokedMethodName = methodName
@@ -108,12 +108,12 @@ func (genericMock *GenericMock) Verify(
}
}
if !invocationCountMatcher.Matches(len(methodInvocations)) {
var paramsOrMatchers interface{} = params
var paramsOrMatchers interface{} = formatParams(params)
if len(globalArgMatchers) != 0 {
paramsOrMatchers = globalArgMatchers
paramsOrMatchers = formatMatchers(globalArgMatchers)
}
GlobalFailHandler(fmt.Sprintf(
"Mock invocation count for method \"%s\" with params %v does not match expectation.\n\n\t%v\n\n\t%v",
"Mock invocation count for %v(%v) does not match expectation.\n\n\t%v\n\n\t%v",
methodName, paramsOrMatchers, invocationCountMatcher.FailureMessage(), formatInteractions(genericMock.allInteractions())))
}
return methodInvocations
@@ -140,11 +140,17 @@ func (genericMock *GenericMock) methodInvocations(methodName string, params []Pa
var invocations []MethodInvocation
if _, exists := genericMock.mockedMethods[methodName]; exists {
for _, invocation := range genericMock.mockedMethods[methodName].invocations {
if (len(matchers) != 0 && Matchers(matchers).Matches(invocation.params)) ||
(reflect.DeepEqual(params, invocation.params) ||
(len(params) == 0 && len(invocation.params) == 0)) {
invocations = append(invocations, invocation)
if len(matchers) != 0 {
if Matchers(matchers).Matches(invocation.params) {
invocations = append(invocations, invocation)
}
} else {
if reflect.DeepEqual(params, invocation.params) ||
(len(params) == 0 && len(invocation.params) == 0) {
invocations = append(invocations, invocation)
}
}
}
}
return invocations
@@ -178,6 +184,16 @@ func formatParams(params []Param) (result string) {
return
}
func formatMatchers(matchers []Matcher) (result string) {
for i, matcher := range matchers {
if i > 0 {
result += ", "
}
result += fmt.Sprintf("%v", matcher)
}
return
}
func sortedMethodNames(interactions map[string][]MethodInvocation) []string {
methodNames := make([]string, len(interactions))
i := 0

View File

@@ -22,6 +22,7 @@ import (
"testing"
. "github.com/petergtz/pegomock"
. "github.com/petergtz/pegomock/matchers"
"github.com/onsi/ginkgo"
. "github.com/onsi/ginkgo"
@@ -42,15 +43,28 @@ func AnyError() error {
}
func AnyRequest() http.Request {
RegisterMatcher(NewAnyMatcher(reflect.TypeOf(http.Request{})))
RegisterMatcher(NewAnyMatcher(reflect.TypeOf((*http.Request)(nil)).Elem()))
return http.Request{}
}
func AnyRequestPtr() *http.Request {
RegisterMatcher(NewAnyMatcher(reflect.TypeOf((*http.Request)(nil))))
RegisterMatcher(NewAnyMatcher(reflect.TypeOf((**http.Request)(nil)).Elem()))
return nil
}
type NeverMatcher struct{}
func (matcher *NeverMatcher) Matches(param Param) bool { return false }
func (matcher *NeverMatcher) FailureMessage() string {
return "This matcher never matches (and is only for testing purposes)"
}
func (matcher *NeverMatcher) String() string { return "NeverMatching" }
func NeverMatchingRequest() http.Request {
RegisterMatcher(&NeverMatcher{})
return http.Request{}
}
var _ = Describe("MockDisplay", func() {
var display *MockDisplay
@@ -71,8 +85,7 @@ var _ = Describe("MockDisplay", func() {
It("fails during verification when mock was not called", func() {
Expect(func() { display.VerifyWasCalledOnce().MultipleParamsAndReturnValue("Hello", 333) }).To(PanicWithMessageTo(HavePrefix(
"Mock invocation count for method \"MultipleParamsAndReturnValue\" with params [Hello 333] " +
"does not match expectation.\n\n\tExpected: 1; but got: 0",
"Mock invocation count for MultipleParamsAndReturnValue(\"Hello\", 333) does not match expectation.\n\n\tExpected: 1; but got: 0",
)))
})
@@ -83,8 +96,7 @@ var _ = Describe("MockDisplay", func() {
It("succeeds verification when verification and invocation are mixed", func() {
Expect(func() { display.VerifyWasCalledOnce().MultipleParamsAndReturnValue("Hello", 333) }).To(PanicWithMessageTo(HavePrefix(
"Mock invocation count for method \"MultipleParamsAndReturnValue\" with params [Hello 333] " +
"does not match expectation.\n\n\tExpected: 1; but got: 0",
expectation{method: "MultipleParamsAndReturnValue(\"Hello\", 333)", expected: "1", actual: "0"}.string(),
)))
display.MultipleParamsAndReturnValue("Hello", 333)
Expect(func() { display.VerifyWasCalledOnce().MultipleParamsAndReturnValue("Hello", 333) }).NotTo(Panic())
@@ -96,8 +108,7 @@ var _ = Describe("MockDisplay", func() {
When(display.MultipleParamsAndReturnValue(AnyString(), EqInt(333))).ThenReturn("Bla")
Expect(func() { display.VerifyWasCalledOnce().MultipleParamsAndReturnValue("Hello", 333) }).To(PanicWithMessageTo(HavePrefix(
"Mock invocation count for method \"MultipleParamsAndReturnValue\" with params [Hello 333] " +
"does not match expectation.\n\n\tExpected: 1; but got: 0",
expectation{method: "MultipleParamsAndReturnValue(\"Hello\", 333)", expected: "1", actual: "0"}.string(),
)))
display.MultipleParamsAndReturnValue("Hello", 333)
@@ -109,8 +120,7 @@ var _ = Describe("MockDisplay", func() {
Expect(func() { display.VerifyWasCalledOnce().MultipleParamsAndReturnValue("And again", 333) }).NotTo(Panic())
Expect(func() { display.VerifyWasCalledOnce().MultipleParamsAndReturnValue("And again", 444) }).To(PanicWithMessageTo(HavePrefix(
"Mock invocation count for method \"MultipleParamsAndReturnValue\" with params [And again 444] " +
"does not match expectation.\n\n\tExpected: 1; but got: 0",
expectation{method: "MultipleParamsAndReturnValue(\"And again\", 444)", expected: "1", actual: "0"}.string(),
)))
})
@@ -157,8 +167,7 @@ var _ = Describe("MockDisplay", func() {
It("fails if verify is called on mock that was not invoked.", func() {
Expect(func() { display.VerifyWasCalledOnce().Show("Some parameter") }).To(PanicWithMessageTo(HavePrefix(
"Mock invocation count for method \"Show\" with params [Some parameter] " +
"does not match expectation.\n\n\tExpected: 1; but got: 0",
expectation{method: "Show(\"Some parameter\")", expected: "1", actual: "0"}.string(),
)))
})
@@ -166,8 +175,7 @@ var _ = Describe("MockDisplay", func() {
display.Show("param")
display.Show("param")
Expect(func() { display.VerifyWasCalledOnce().Show("param") }).To(PanicWithMessageTo(HavePrefix(
"Mock invocation count for method \"Show\" with params [param] " +
"does not match expectation.\n\n\tExpected: 1; but got: 2",
expectation{method: "Show(\"param\")", expected: "1", actual: "2"}.string(),
)))
})
@@ -230,7 +238,7 @@ var _ = Describe("MockDisplay", func() {
It("fails during verification", func() {
When(display.SomeValue()).ThenReturn("Hello")
Expect(func() { display.VerifyWasCalledOnce().SomeValue() }).To(PanicWithMessageTo(HavePrefix(
"Mock invocation count for method \"SomeValue\" with params [] does not match expectation.\n\n\tExpected: 1; but got: 0",
expectation{method: "SomeValue()", expected: "1", actual: "0"}.string(),
)))
})
})
@@ -245,8 +253,7 @@ var _ = Describe("MockDisplay", func() {
It("fails during verification if values are not matching", func() {
Expect(func() { display.VerifyWasCalledOnce().Flash("Hello", 666) }).To(PanicWithMessageTo(HavePrefix(
"Mock invocation count for method \"Flash\" with params [Hello 666] " +
"does not match expectation.\n\n\tExpected: 1; but got: 0",
expectation{method: "Flash(\"Hello\", 666)", expected: "1", actual: "0"}.string(),
)))
})
@@ -260,8 +267,7 @@ var _ = Describe("MockDisplay", func() {
It("fails during verification when using invalid Eq-matchers ", func() {
Expect(func() { display.VerifyWasCalledOnce().Flash(EqString("Invalid"), EqInt(-1)) }).To(PanicWithMessageTo(HavePrefix(
"Mock invocation count for method \"Flash\" with params [Eq(Invalid) Eq(-1)] " +
"does not match expectation.\n\n\tExpected: 1; but got: 0",
expectation{method: "Flash(Eq(Invalid), Eq(-1))", expected: "1", actual: "0"}.string(),
)))
})
@@ -294,15 +300,13 @@ var _ = Describe("MockDisplay", func() {
It("fails during verification if verifying with VerifyWasCalledOnce", func() {
Expect(func() { display.VerifyWasCalledOnce().Flash("Hello", 333) }).To(PanicWithMessageTo(HavePrefix(
"Mock invocation count for method \"Flash\" with params [Hello 333] " +
"does not match expectation.\n\n\tExpected: 1; but got: 2",
expectation{method: "Flash(\"Hello\", 333)", expected: "1", actual: "2"}.string(),
)))
})
It("fails during verification if verifying with Times(1)", func() {
Expect(func() { display.VerifyWasCalled(Times(1)).Flash("Hello", 333) }).To(PanicWithMessageTo(HavePrefix(
"Mock invocation count for method \"Flash\" with params [Hello 333] " +
"does not match expectation.\n\n\tExpected: 1; but got: 2",
expectation{method: "Flash(\"Hello\", 333)", expected: "1", actual: "2"}.string(),
)))
})
@@ -316,8 +320,7 @@ var _ = Describe("MockDisplay", func() {
It("fails during verification when using AtLeast(3)", func() {
Expect(func() { display.VerifyWasCalled(AtLeast(3)).Flash("Hello", 333) }).To(PanicWithMessageTo(HavePrefix(
"Mock invocation count for method \"Flash\" with params [Hello 333] " +
"does not match expectation.\n\n\tExpected: at least 3; but got: 2",
expectation{method: "Flash(\"Hello\", 333)", expected: "at least 3", actual: "2"}.string(),
)))
})
@@ -327,8 +330,7 @@ var _ = Describe("MockDisplay", func() {
It("fails during verification when using Never()", func() {
Expect(func() { display.VerifyWasCalled(Never()).Flash("Hello", 333) }).To(PanicWithMessageTo(HavePrefix(
"Mock invocation count for method \"Flash\" with params [Hello 333] " +
"does not match expectation.\n\n\tExpected: 0; but got: 2",
expectation{method: "Flash(\"Hello\", 333)", expected: "0", actual: "2"}.string(),
)))
})
})
@@ -396,7 +398,7 @@ var _ = Describe("MockDisplay", func() {
display.VerifyWasCalledInOrder(Once(), inOrder).Flash("Hello", 111)
display.VerifyWasCalledInOrder(Once(), inOrder).Flash("and again", 333)
}).To(PanicWithMessageTo(HavePrefix(
"Expected function call \"Flash\" with params [Hello 111] before function call \"Flash\" with params [again 222]",
"Expected function call Flash(\"Hello\", 111) before function call Flash(\"again\", 222)",
)))
})
@@ -464,8 +466,7 @@ var _ = Describe("MockDisplay", func() {
display.InterfaceParam(3)
display.VerifyWasCalledOnce().InterfaceParam(AnyFloat32())
}).To(PanicWithMessageTo(HavePrefix(
"Mock invocation count for method \"InterfaceParam\" with params [Any(float32)] " +
"does not match expectation.\n\n\tExpected: 1; but got: 0",
expectation{method: "InterfaceParam(Any(float32))", expected: "1", actual: "0"}.string(),
)))
})
@@ -474,8 +475,7 @@ var _ = Describe("MockDisplay", func() {
display.InterfaceParam(3.141)
display.VerifyWasCalledOnce().InterfaceParam(AnyInt())
}).To(PanicWithMessageTo(HavePrefix(
"Mock invocation count for method \"InterfaceParam\" with params [Any(int)] " +
"does not match expectation.\n\n\tExpected: 1; but got: 0",
expectation{method: "InterfaceParam(Any(int))", expected: "1", actual: "0"}.string(),
)))
})
@@ -494,8 +494,7 @@ var _ = Describe("MockDisplay", func() {
display.InterfaceParam(nil)
display.VerifyWasCalledOnce().InterfaceParam(AnyInt())
}).To(PanicWithMessageTo(HavePrefix(
"Mock invocation count for method \"InterfaceParam\" with params [Any(int)] " +
"does not match expectation.\n\n\tExpected: 1; but got: 0",
expectation{method: "InterfaceParam(Any(int))", expected: "1", actual: "0"}.string(),
)))
})
@@ -514,6 +513,19 @@ var _ = Describe("MockDisplay", func() {
display.VerifyWasCalledOnce().NetHttpRequestParam(AnyRequest())
})
It("Succeeds when http.Request-parameter is passed as null value to interface{} and verified as any http.Request", func() {
display.InterfaceParam(http.Request{})
display.VerifyWasCalledOnce().InterfaceParam(AnyRequest())
})
It("Fails when *pointer* to http.Request-parameter is passed to interface{} and verified as any http.Request", func() {
display.InterfaceParam(&http.Request{})
Expect(func() { display.VerifyWasCalledOnce().InterfaceParam(AnyRequest()) }).To(PanicWithMessageTo(SatisfyAll(
ContainSubstring("InterfaceParam(Any(http.Request))"),
ContainSubstring("InterfaceParam(&http.Request{Method"),
)))
})
It("Succeeds when http.Request-Pointer-parameter is passed as nil and verified as any *http.Request", func() {
display.NetHttpRequestPtrParam(nil)
display.VerifyWasCalledOnce().NetHttpRequestPtrParam(AnyRequestPtr())
@@ -523,7 +535,41 @@ var _ = Describe("MockDisplay", func() {
display.NetHttpRequestPtrParam(&http.Request{})
display.VerifyWasCalledOnce().NetHttpRequestPtrParam(AnyRequestPtr())
})
})
Describe("Generated matchers", func() {
It("Succeeds when map-parameter is passed to interface{} and verified as any map", func() {
display.InterfaceParam(map[string]http.Request{"foo": http.Request{}})
display.VerifyWasCalledOnce().InterfaceParam(AnyMapOfStringToHttpRequest())
})
It("Fails when string parameter is passed to interface{} and verified as any map", func() {
display.InterfaceParam("This will not match")
Expect(func() { display.VerifyWasCalledOnce().InterfaceParam(AnyMapOfStringToHttpRequest()) }).To(PanicWithMessageTo(SatisfyAll(
ContainSubstring("InterfaceParam(Any(map[string]http.Request))"),
ContainSubstring("InterfaceParam(\"This will not match\")"),
)))
})
It("Succeeds when map-parameter is passed to interface{} and verified as eq map", func() {
display.InterfaceParam(map[string]http.Request{"foo": http.Request{}})
display.VerifyWasCalledOnce().InterfaceParam(EqMapOfStringToHttpRequest(map[string]http.Request{"foo": http.Request{}}))
})
})
Describe("Logic around matchers and verification", func() {
// TODO maybe this should go somewhere else
It("Fails when http.Request-parameter is passed as null value and verified as never matching http.Request", func() {
display.NetHttpRequestParam(http.Request{})
Expect(func() { display.VerifyWasCalledOnce().NetHttpRequestParam(NeverMatchingRequest()) }).
To(PanicWithMessageTo(Equal(`Mock invocation count for NetHttpRequestParam(NeverMatching) does not match expectation.
Expected: 1; but got: 0
But other interactions with this mock were:
NetHttpRequestParam(http.Request{Method:"", URL:(*url.URL)(nil), Proto:"", ProtoMajor:0, ProtoMinor:0, Header:http.Header(nil), Body:io.ReadCloser(nil), GetBody:(func() (io.ReadCloser, error))(nil), ContentLength:0, TransferEncoding:[]string(nil), Close:false, Host:"", Form:url.Values(nil), PostForm:url.Values(nil), MultipartForm:(*multipart.Form)(nil), Trailer:http.Header(nil), RemoteAddr:"", RequestURI:"", TLS:(*tls.ConnectionState)(nil), Cancel:(<-chan struct {})(nil), Response:(*http.Response)(nil), ctx:context.Context(nil)})
`)))
})
})
Describe("Stubbing with multiple ThenReturns versus multiple stubbings with same parameters", func() {
@@ -553,7 +599,7 @@ var _ = Describe("MockDisplay", func() {
display.Flash("Again", 456)
Expect(func() { display.VerifyWasCalledOnce().Flash("wrong string", -987) }).To(PanicWith(
"Mock invocation count for method \"Flash\" with params [wrong string -987] " +
"Mock invocation count for Flash(\"wrong string\", -987) " +
"does not match expectation.\n\n\tExpected: 1; but got: 0\n\n" +
"\tBut other interactions with this mock were:\n" +
"\tFlash(\"Hello\", 123)\n" +
@@ -566,7 +612,7 @@ var _ = Describe("MockDisplay", func() {
display.Flash("Hello", 123)
Expect(func() { display.VerifyWasCalledOnce().Flash("wrong string", -987) }).To(PanicWith(
"Mock invocation count for method \"Flash\" with params [wrong string -987] " +
"Mock invocation count for Flash(\"wrong string\", -987) " +
"does not match expectation.\n\n\tExpected: 1; but got: 0\n\n" +
"\tBut other interactions with this mock were:\n" +
"\tFlash(\"Hello\", 123)\n" +
@@ -577,7 +623,7 @@ var _ = Describe("MockDisplay", func() {
It("formats params in interactions with Go syntax for better readability", func() {
display.NetHttpRequestParam(http.Request{Host: "x.com"})
Expect(func() { display.VerifyWasCalledOnce().NetHttpRequestParam(http.Request{Host: "y.com"}) }).To(PanicWith(
`Mock invocation count for method "NetHttpRequestParam" with params [{ <nil> 0 0 map[] <nil> <nil> 0 [] false y.com map[] map[] <nil> map[] <nil> <nil> <nil> <nil>}] does not match expectation.
`Mock invocation count for NetHttpRequestParam(http.Request{Method:"", URL:(*url.URL)(nil), Proto:"", ProtoMajor:0, ProtoMinor:0, Header:http.Header(nil), Body:io.ReadCloser(nil), GetBody:(func() (io.ReadCloser, error))(nil), ContentLength:0, TransferEncoding:[]string(nil), Close:false, Host:"y.com", Form:url.Values(nil), PostForm:url.Values(nil), MultipartForm:(*multipart.Form)(nil), Trailer:http.Header(nil), RemoteAddr:"", RequestURI:"", TLS:(*tls.ConnectionState)(nil), Cancel:(<-chan struct {})(nil), Response:(*http.Response)(nil), ctx:context.Context(nil)}) does not match expectation.
Expected: 1; but got: 0
@@ -589,7 +635,7 @@ var _ = Describe("MockDisplay", func() {
It("shows no interactions if there were none", func() {
Expect(func() { display.VerifyWasCalledOnce().Flash("wrong string", -987) }).To(PanicWith(
"Mock invocation count for method \"Flash\" with params [wrong string -987] " +
"Mock invocation count for Flash(\"wrong string\", -987) " +
"does not match expectation.\n\n\tExpected: 1; but got: 0\n\n" +
"\tThere were no other interactions with this mock",
))
@@ -714,3 +760,14 @@ func flattenStringSliceOfSlices(sliceOfSlices [][]string) (result []string) {
}
return
}
type expectation struct {
method string
expected string
actual string
}
func (e expectation) string() string {
return fmt.Sprintf("Mock invocation count for %v does not match expectation.\n\n\tExpected: %v; but got: %v",
e.method, e.expected, e.actual)
}

View File

@@ -28,5 +28,5 @@ var _ = It("Generate mocks", func() {
filehandling.GenerateMockFile(
[]string{"github.com/petergtz/pegomock/test_interface", "Display"},
"../../mock_display_test.go", "pegomock_test",
"", false, os.Stdout, false)
"", false, os.Stdout, false, true)
})

View File

@@ -28,5 +28,5 @@ var _ = It("Generate mocks", func() {
filehandling.GenerateMockFile(
[]string{"../../test_interface/display.go"},
"../../mock_display_test.go", "pegomock_test",
"", false, os.Stdout, false)
"", false, os.Stdout, false, true)
})

View File

@@ -30,5 +30,5 @@ var _ = It("Generate mocks", func() {
filehandling.GenerateMockFile(
[]string{"github.com/petergtz/pegomock/test_interface", "Display"},
"../../mock_display_test.go", "pegomock_test",
"", false, os.Stdout, true)
"", false, os.Stdout, true, true)
})

View File

@@ -36,15 +36,16 @@ import (
const mockFrameworkImportPath = "github.com/petergtz/pegomock"
func GenerateOutput(ast *model.Package, source, packageOut, selfPackage string) ([]byte, error) {
g := new(generator)
func GenerateOutput(ast *model.Package, source, packageOut, selfPackage string) ([]byte, map[string]string) {
g := generator{typesSet: make(map[string]string)}
g.generateCode(source, ast, packageOut, selfPackage)
return g.formattedOutput(), nil
return g.formattedOutput(), g.typesSet
}
type generator struct {
buf bytes.Buffer
packageMap map[string]string // map from import path to package name
typesSet map[string]string
}
func (g *generator) generateCode(source string, pkg *model.Package, pkgName, selfPackage string) {
@@ -96,15 +97,18 @@ func generateUniquePackageNamesFor(importPaths map[string]bool) (packageMap, non
packageMap[importPath] = packageName
packageNamesAlreadyUsed[packageName] = true
vendorParsedImportPath := importPath
if split := strings.Split(importPath, "/vendor/"); len(split) > 1 {
vendorParsedImportPath = split[1]
}
nonVendorPackageMap[vendorParsedImportPath] = packageName
nonVendorPackageMap[vendorCleaned(importPath)] = packageName
}
return
}
func vendorCleaned(importPath string) string {
if split := strings.Split(importPath, "/vendor/"); len(split) > 1 {
return split[1]
}
return importPath
}
// sanitize cleans up a string to make a suitable package name.
// pkgName in reflect mode is the base name of the import path,
// which might have characters that are illegal to have in package names.
@@ -136,6 +140,9 @@ func (g *generator) generateMockFor(iface *model.Interface, selfPackage string)
for _, method := range iface.Methods {
g.generateMockMethod(mockTypeName, method, selfPackage)
g.emptyLine()
addTypesFromMethodParamsTo(g.typesSet, method.In, g.packageMap)
addTypesFromMethodParamsTo(g.typesSet, method.Out, g.packageMap)
}
g.generateMockVerifyMethods(iface.Name)
g.generateVerifierType(iface.Name)
@@ -342,6 +349,112 @@ func argDataFor(method *model.Method, packageMap map[string]string, pkgOverride
return
}
func addTypesFromMethodParamsTo(typesSet map[string]string, params []*model.Parameter, packageMap map[string]string) {
for _, param := range params {
switch typedType := param.Type.(type) {
case *model.NamedType, *model.PointerType, *model.ArrayType, *model.MapType, *model.ChanType:
if _, exists := typesSet[underscoreNameFor(typedType, packageMap)]; !exists {
typesSet[underscoreNameFor(typedType, packageMap)] = generateMatcherSourceCode(typedType, packageMap)
}
case *model.FuncType:
// matcher generation for funcs not supported yet
// TODO implement
case model.PredeclaredType:
// skip. These come as part of pegomock.
default:
panic("Should not get here")
}
}
}
func generateMatcherSourceCode(t model.Type, packageMap map[string]string) string {
return fmt.Sprintf(`package matchers
import (
"reflect"
"github.com/petergtz/pegomock"
%v
)
func Any%v() %v {
pegomock.RegisterMatcher(pegomock.NewAnyMatcher(reflect.TypeOf((*(%v))(nil)).Elem()))
var nullValue %v
return nullValue
}
func Eq%v(value %v) %v {
pegomock.RegisterMatcher(&pegomock.EqMatcher{Value: value})
var nullValue %v
return nullValue
}
`,
optionalPackageOf(t, packageMap),
camelcaseNameFor(t, packageMap),
t.String(packageMap, ""),
t.String(packageMap, ""),
t.String(packageMap, ""),
camelcaseNameFor(t, packageMap),
t.String(packageMap, ""),
t.String(packageMap, ""),
t.String(packageMap, ""),
)
}
func optionalPackageOf(t model.Type, packageMap map[string]string) string {
switch typedType := t.(type) {
case model.PredeclaredType:
return ""
case *model.NamedType:
return fmt.Sprintf("%v \"%v\"", packageMap[typedType.Package], vendorCleaned(typedType.Package))
case *model.PointerType:
return optionalPackageOf(typedType.Type, packageMap)
case *model.ArrayType:
return optionalPackageOf(typedType.Type, packageMap)
case *model.MapType:
return optionalPackageOf(typedType.Key, packageMap) + "\n" + optionalPackageOf(typedType.Value, packageMap)
case *model.ChanType:
return optionalPackageOf(typedType.Type, packageMap)
// TODO:
// case *model.FuncType:
default:
panic(fmt.Sprintf("TODO implement optionalPackageOf for: %v\nis type of %T\n", typedType, typedType))
}
}
func spaceSeparatedNameFor(t model.Type, packageMap map[string]string) string {
switch typedType := t.(type) {
case model.PredeclaredType:
return typedType.String(packageMap, "")
case *model.NamedType:
return strings.Replace((typedType.String(packageMap, "")), ".", " ", -1)
case *model.PointerType:
return "ptr to " + spaceSeparatedNameFor(typedType.Type, packageMap)
case *model.ArrayType:
if typedType.Len == -1 {
return "slice of " + spaceSeparatedNameFor(typedType.Type, packageMap)
} else {
return "array of " + spaceSeparatedNameFor(typedType.Type, packageMap)
}
case *model.MapType:
return "map of " + spaceSeparatedNameFor(typedType.Key, packageMap) + " to " + spaceSeparatedNameFor(typedType.Value, packageMap)
case *model.ChanType:
return "chan of " + spaceSeparatedNameFor(typedType.Type, packageMap)
// TODO:
// case *model.FuncType:
default:
return fmt.Sprintf("TODO implement matcher for: %v\nis type of %T\n", typedType, typedType)
}
}
func camelcaseNameFor(t model.Type, packageMap map[string]string) string {
return strings.Replace(strings.Title(strings.Replace(spaceSeparatedNameFor(t, packageMap), "_", " ", -1)), " ", "", -1)
}
func underscoreNameFor(t model.Type, packageMap map[string]string) string {
return strings.ToLower(strings.Replace(spaceSeparatedNameFor(t, packageMap), " ", "_", -1))
}
func (g *generator) p(format string, args ...interface{}) *generator {
fmt.Fprintf(&g.buf, format+"\n", args...)
return g

View File

@@ -0,0 +1,13 @@
package mockgen_test
import (
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"testing"
)
func TestMockgen(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "Mockgen Suite")
}

View File

@@ -0,0 +1,41 @@
package mockgen_test
import (
"github.com/petergtz/pegomock/mockgen"
"github.com/petergtz/pegomock/modelgen/loader"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)
var _ = Describe("Mockgen", func() {
Context("matcherSourceCodes", func() {
It("uses correct naming pattern with underscores for keys, and correct types etc. in source code", func() {
ast, e := loader.GenerateModel("github.com/petergtz/pegomock/test_interface", "Display")
Expect(e).NotTo(HaveOccurred())
_, matcherSourceCodes := mockgen.GenerateOutput(ast, "irrelevant", "test_package", "")
Expect(matcherSourceCodes).To(SatisfyAll(
HaveLen(5),
HaveKeyWithValue("http_request", SatisfyAll(
ContainSubstring("http \"net/http\""),
ContainSubstring("func AnyHttpRequest() http.Request"),
)),
HaveKeyWithValue("ptr_to_http_request", SatisfyAll(
ContainSubstring("http \"net/http\""),
ContainSubstring("func AnyPtrToHttpRequest() *http.Request"),
)),
HaveKeyWithValue("slice_of_string",
ContainSubstring("func AnySliceOfString() []string"),
),
HaveKeyWithValue("map_of_string_to_http_request", SatisfyAll(
ContainSubstring("http \"net/http\""),
ContainSubstring("func AnyMapOfStringToHttpRequest() map[string]http.Request"),
)),
HaveKeyWithValue("io_readcloser", SatisfyAll(
ContainSubstring("func AnyIoReadCloser() io.ReadCloser"),
)),
))
})
})
})

View File

@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
package pegomock_test
package modelgen_test
import (
"fmt"

View File

@@ -5,6 +5,7 @@ import (
"io"
"io/ioutil"
"log"
"os"
"path/filepath"
"strings"
@@ -23,7 +24,8 @@ func GenerateMockFileInOutputDir(
selfPackage string,
debugParser bool,
out io.Writer,
useExperimentalModelGen bool) {
useExperimentalModelGen bool,
shouldGenerateMatchers bool) {
GenerateMockFile(
args,
OutputFilePath(args, outputDirPath, outputFilePathOverride),
@@ -31,7 +33,8 @@ func GenerateMockFileInOutputDir(
selfPackage,
debugParser,
out,
useExperimentalModelGen)
useExperimentalModelGen,
shouldGenerateMatchers)
}
func OutputFilePath(args []string, outputDirPath string, outputFilePathOverride string) string {
@@ -44,16 +47,30 @@ func OutputFilePath(args []string, outputDirPath string, outputFilePathOverride
}
}
func GenerateMockFile(args []string, outputFilePath string, packageOut string, selfPackage string, debugParser bool, out io.Writer, useExperimentalModelGen bool) {
output := GenerateMockSourceCode(args, packageOut, selfPackage, debugParser, out, useExperimentalModelGen)
func GenerateMockFile(args []string, outputFilePath string, packageOut string, selfPackage string, debugParser bool, out io.Writer, useExperimentalModelGen bool, shouldGenerateMatchers bool) {
mockSourceCode, matcherSourceCodes := GenerateMockSourceCode(args, packageOut, selfPackage, debugParser, out, useExperimentalModelGen)
err := ioutil.WriteFile(outputFilePath, output, 0664)
err := ioutil.WriteFile(outputFilePath, mockSourceCode, 0664)
if err != nil {
panic(fmt.Errorf("Failed writing to destination: %v", err))
}
if shouldGenerateMatchers {
matchersPath := filepath.Join(filepath.Dir(outputFilePath), "matchers")
err = os.MkdirAll(matchersPath, 0755)
if err != nil {
panic(fmt.Errorf("Failed making dirs \"%v\": %v", matchersPath, err))
}
for matcherTypeName, matcherSourceCode := range matcherSourceCodes {
err := ioutil.WriteFile(filepath.Join(matchersPath, matcherTypeName+".go"), []byte(matcherSourceCode), 0664)
if err != nil {
panic(fmt.Errorf("Failed writing to destination: %v", err))
}
}
}
}
func GenerateMockSourceCode(args []string, packageOut string, selfPackage string, debugParser bool, out io.Writer, useExperimentalModelGen bool) []byte {
func GenerateMockSourceCode(args []string, packageOut string, selfPackage string, debugParser bool, out io.Writer, useExperimentalModelGen bool) ([]byte, map[string]string) {
var err error
var ast *model.Package
@@ -81,9 +98,5 @@ func GenerateMockSourceCode(args []string, packageOut string, selfPackage string
ast.Print(out)
}
output, err := mockgen.GenerateOutput(ast, src, packageOut, selfPackage)
if err != nil {
panic(fmt.Errorf("Failed generating mock: %v", err))
}
return output
return mockgen.GenerateOutput(ast, src, packageOut, selfPackage)
}

View File

@@ -47,8 +47,10 @@ func Run(cliArgs []string, out io.Writer, app *kingpin.Application, done chan bo
// TODO: self_package was taken as is from GoMock.
// Still don't understand what it's really there for.
// So for now it's not tested.
selfPackage = generateCmd.Flag("self_package", "If set, the package this mock will be part of.").String()
debugParser = generateCmd.Flag("debug", "Print debug information.").Short('d').Bool()
selfPackage = generateCmd.Flag("self_package", "If set, the package this mock will be part of.").String()
debugParser = generateCmd.Flag("debug", "Print debug information.").Short('d').Bool()
shouldGenerateMatchers = generateCmd.Flag("generate-matchers", "Generate matchers for all non built-in types in a \"matchers\" "+
"directory in the same directory where the mock file gets generated.").Short('m').Default("false").Bool()
useExperimentalModelGen = generateCmd.Flag("use-experimental-model-gen", "pegomock includes a new experimental source parser based on "+
"golang.org/x/tools/go/loader. It's currently experimental, but should be more powerful "+
"than the current reflect-based modelgen. E.g. reflect cannot detect method parameter names,"+
@@ -81,7 +83,8 @@ func Run(cliArgs []string, out io.Writer, app *kingpin.Application, done chan bo
*selfPackage,
*debugParser,
out,
*useExperimentalModelGen)
*useExperimentalModelGen,
*shouldGenerateMatchers)
case watchCmd.FullCommand():
var targetPaths []string

View File

@@ -104,10 +104,13 @@ var _ = Describe("CLI", func() {
It(`generates a file mock_vendordisplay_test.go that contains 'import ( vendored_package "github.com/petergtz/vendored_package" )'`, func() {
main.Run(cmd("pegomock generate VendorDisplay"), os.Stdout, app, done)
main.Run(cmd("pegomock generate -m VendorDisplay"), os.Stdout, app, done)
Expect(joinPath(packageDir, "mock_vendordisplay_test.go")).To(SatisfyAll(
BeAnExistingFile(),
BeAFileContainingSubString(`vendored_package "github.com/petergtz/vendored_package"`)))
Expect(joinPath(packageDir, "matchers", "vendored_package_interface.go")).To(SatisfyAll(
BeAnExistingFile(),
BeAFileContainingSubString(`vendored_package "github.com/petergtz/vendored_package"`)))
})
})

View File

@@ -91,7 +91,7 @@ func (updater *MockFileUpdater) updateMockFiles(targetPath string) {
sourceArgs, err := util.SourceArgs(*lineArgs)
util.PanicOnError(err)
generatedMockSourceCode := filehandling.GenerateMockSourceCode(sourceArgs, *packageOut, *selfPackage, false, os.Stdout, false)
generatedMockSourceCode, _ := filehandling.GenerateMockSourceCode(sourceArgs, *packageOut, *selfPackage, false, os.Stdout, false)
mockFilePath := filehandling.OutputFilePath(sourceArgs, ".", *destination)
hasChanged := util.WriteFileIfChanged(mockFilePath, generatedMockSourceCode)

View File

@@ -1,15 +1,20 @@
#!/bin/bash
set -ex
cd $(dirname $0)/..
PACKAGES_TO_SKIP='generate_test_mocks/xtools_go_loader,generate_test_mocks/gomock_reflect,generate_test_mocks/gomock_source'
rm -f mock_display_test.go
rm -rf matchers
$GOPATH/bin/ginkgo -succinct generate_test_mocks/xtools_go_loader
$GOPATH/bin/ginkgo -r -skipPackage=generate_test_mocks/xtools_go_loader,generate_test_mocks/gomock_reflect,generate_test_mocks/gomock_source --randomizeAllSpecs --randomizeSuites --race --trace -cover
$GOPATH/bin/ginkgo -r -skipPackage=$PACKAGES_TO_SKIP --randomizeAllSpecs --randomizeSuites --race --trace -cover
rm -f mock_display_test.go
rm -rf matchers
$GOPATH/bin/ginkgo -succinct generate_test_mocks/gomock_reflect
$GOPATH/bin/ginkgo -r -skipPackage=generate_test_mocks/xtools_go_loader,generate_test_mocks/gomock_reflect,generate_test_mocks/gomock_source --randomizeAllSpecs --randomizeSuites --race --trace -cover
$GOPATH/bin/ginkgo --randomizeAllSpecs --randomizeSuites --race --trace -cover
rm -f mock_display_test.go
rm -rf matchers
$GOPATH/bin/ginkgo -succinct generate_test_mocks/gomock_source
$GOPATH/bin/ginkgo -r -skipPackage=generate_test_mocks/xtools_go_loader,generate_test_mocks/gomock_reflect,generate_test_mocks/gomock_source --randomizeAllSpecs --randomizeSuites --race --trace -cover
$GOPATH/bin/ginkgo --randomizeAllSpecs --randomizeSuites --race --trace -cover

View File

@@ -15,6 +15,7 @@
package test_interface
import "net/http"
import "io"
// Display is some sample interface to be mocked.
type Display interface {
@@ -24,6 +25,7 @@ type Display interface {
MultipleValues() (string, int, float32)
MultipleParamsAndReturnValue(s string, i int) string
ArrayParam(array []string)
MapParam(m map[string]http.Request)
FloatParam(float32)
InterfaceParam(interface{})
InterfaceReturnValue() interface{}
@@ -34,4 +36,5 @@ type Display interface {
FuncReturnValue() func()
VariadicParam(v ...string)
NormalAndVariadicParam(s string, i int, v ...string)
CamelCaseTypeParam(camelCaseParam io.ReadCloser)
}